这是一个非常简单的代码:
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)。
但是它无法在 Visual Studio 2019 with C++ 17 设置中编译。
error C2672: 'test': no matching overloaded function found
error C2783: 'void test(std::tuple<_Types...>)': could not deduce template argument for '__formal'
但是我发现它在 GCC 和 Clang 中编译得很好。为什么看似无害的代码会失败?
有趣的是如果我替换sizeof...(Args)
至 2
然后它突然起作用了。
编辑:我原来的问题没有提供类型 enable_if
,但我发现 void*
在 C++ 17 中不允许作为非类型模板参数。但这没关系。 因为即使我更改为 std::enable_if<std::less<int>()(sizeof...(Args), 3), int>
, 它仍然失败并出现同样的错误。
最佳答案
根据 [comparisons.less] :
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;
Returns:
x < y
.
运算符是constexpr
.因此,就 less
而言,您的代码没有问题。很关心。
然而,从技术上讲,MSVC 实际上就在这里——非类型模板参数不应具有类型 void*
在 C++17 中。 MSVC 实际上诊断了这一点。无论如何,这纯属巧合。
您可以使用 <
直接作为解决方法:
template <typename... Args,
typename std::enable_if<(sizeof...(Args) < 3), int>::type = 0>
void test(std::tuple<Args...>)
(请注意,使用 int
而不是 void*
,因此语言学究绝对无话可说。)
关于c++ - enable_if + std::less + sizeof... 的组合使 MSVC 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56880663/