这是一个非常简单的代码:
template <typename... Args,
typename std::enable_if<std::less<int>()(sizeof...(Args), 3), int>::type* = nullptr>
void test(std::tuple<Args...>)
{
}
int main()
{
test(std::make_tuple(1, 2));
}
这只是具有某些enable_if
条件的简单函数模板。 (用于进一步的SFINAE)。
但是它无法在带有C ++ 17的Visual Studio 2019 中编译。
error C2672: 'test': no matching overloaded function found
error C2783: 'void test(std::tuple<_Types...>)': could not deduce template argument for '__formal'
但是我发现它在GCC和Clang中编译良好 strong>。为什么看似纯真的代码失败了?
有趣的是,如果我将sizeof...(Args)
替换为2
,那么它突然起作用了。
编辑:我最初的问题未在enable_if
中提供类型,但我发现在C ++ 17中不允许将void*
作为非类型模板参数。 但这没关系。因为即使我更改为std::enable_if<std::less<int>()(sizeof...(Args), 3), int>
,它仍然会失败,并显示相同的错误。
答案 0 :(得分:3)
template <class T = void> struct less { constexpr bool operator()(const T& x, const T& y) const; };
constexpr bool operator()(const T& x, const T& y) const;
返回:
x < y
。
运算符为constexpr
。因此,就less
而言,您的代码是可以的。
但是,从技术上讲,MSVC实际上就在这里-非类型模板参数在C ++ 17中不得具有类型void*
。 MSVC实际上诊断出了这一点。无论如何,那纯粹是巧合。
您可以直接使用<
作为解决方法:
template <typename... Args,
typename std::enable_if<(sizeof...(Args) < 3), int>::type = 0>
void test(std::tuple<Args...>)
(请注意,使用int
代替了void*
,因此语言学习者绝对无话可说。)