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

允我心安 提交于 2019-12-23 08:12:33

问题


Here is an extremely simple code :

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));
}

It's just simple function template with some enable_if condition. (for further SFINAE).

But it fails to compile in Visual Studio 2019 with C++ 17 setup.

error C2672:  'test': no matching overloaded function found
error C2783:  'void test(std::tuple<_Types...>)': could not deduce template argument for '__formal'

However I found that it compiles well in GCC and Clang. Why does that seemingly innocent code fail?

funny thing is if I substitute sizeof...(Args) to 2 then it suddenly works.

Edit : My original question doesn't provide type in enable_if, but I found that void* is not allowed as a non-type template parameter in C++ 17. But It doesn't matter. Because even if I change to std::enable_if<std::less<int>()(sizeof...(Args), 3), int>, it still fails with same error.


回答1:


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;

Returns: x < y.

The operator is constexpr. Therefore, your code is fine as far as the less is concerned.

However, technically speaking, MSVC is actually right here — non-type template parameters shall not have type void* in C++17. MSVC actually diagnosed that. That's purely a coincidence, anyway.

You can use < directly as a workaround:

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

(Note that int is used instead of void*, so that a language pedant has absolutely nothing to say.)



来源:https://stackoverflow.com/questions/56880663/combination-of-enable-if-stdless-sizeof-makes-msvc-fail

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!