引入 std::enable_if 后出现"No match"错误

"No match" error after introducing std::enable_if

本文关键字:No match 错误 std enable if 引入      更新时间:2023-10-16

我有一个运算符(在本例中为 operator&= ,但这不是问题(,直到我将std::enable_if_t引入组合。

用代码示例解释更简单:

template<typename T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>>>
MyClass& MyClass::operator&=(T d)
{ /*... */ }
// then in main
MyClass a;
a &= static_cast<unsigned char>42;
a &= (unsigned long long)47;

如果我注释掉std::enable_if_t块,那么它会按预期编译和运行,但是一旦我把它放在那里,它就会在格式上产生错误

test.cpp:42:7: error: no match for ‘operator&=’ (operand types are ‘MyClass’ and ‘unsigned char’)
  a &= static_cast<unsigned char>(42);
  ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from test.cpp:4:0:
file.hpp:69:103: note: candidate: template<class T, typename std::enable_if<(is_integral_v<T> && is_unsigned_v<T>), void>::type <anonymous> > MyClass& MyClass::operator&=(T)
  template<typename T, std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>>> MyClass& operator&=(T d);
                                                                                                  ^~~~~~~~
file.hpp:69:103: note:   template argument deduction/substitution failed:
test.cpp:42:39: note:   couldn't deduce template parameter ‘<anonymous>’
  a &= static_cast<unsigned char>(42);

我觉得我在这里错过了一些简单的东西。我什至已经尝试通过调用a.operator&=<unsigned char>(static_cast<unsigned char>(42))来提示编译器以查看它是否可以工作,但它没有。

typename class您需要在定义

template<typename T, class = std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>>>
                     ^^^^^
MyClass& MyClass::operator&=(T d)

当条件std::is_integral_v<T> && std::is_unsigned_v<T>为真时,enable_if::type void。没有class void被视为非类型模板参数有什么问题(void不能用作非类型参数引用(。

通过使用 class/typename,第二个参数被定义为类型参数,如果 enable_if 中的条件为真,则取 void - class SomeTypeName = void,或者当enable_if的条件为 false 时,此函数模板从重载中丢弃。