enable_if std的组合:: Less sizeof ..使MSVC失败

combination of enable_if + std::less + sizeof... makes MSVC fail

本文关键字:Less sizeof MSVC 失败 组合 if std enable      更新时间:2023-10-16

这是一个非常简单的代码:

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中使用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,那么它突然起作用。

edit :我的原始问题不提供enable_if中的类型,但我发现void*不允许作为C 17中的非类型模板参数。Matter。,因为即使我更改为std::enable_if<std::less<int>()(sizeof...(Args), 3), int>它仍然会失败,但同样的错误。

per [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;

返回: x < y

操作员是constexpr。因此,就less而言,您的代码很好。

但是,从技术上讲,MSVC实际上就在这里&mdash;非型模板参数不得在C 中具有void*型。MSVC实际上诊断出来。无论如何,这纯粹是巧合。

您可以直接将<用作解决方法:

template <typename... Args,
  typename std::enable_if<(sizeof...(Args) < 3), int>::type = 0>
void test(std::tuple<Args...>)

(请注意,使用int代替void*,因此语言pedant绝对没有话要说。(