I have an operator (in this case operator&=
, but that is not an issue) that works fine, until i introduce std::enable_if_t
into the mix.
It is simpler to explain with the code example:
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;
If i comment out the std::enable_if_t
block, then it compiles and runs as expected, but once i place it in there it produces errors in the format
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);
I feel like i am missing something simple here. I have even already tried hinting the compiler by calling a.operator&=<unsigned char>(static_cast<unsigned char>(42))
to see if it will work, but it doesn't.
You need to use class
/typename
at the second template parameter in definition of
template<typename T, class = std::enable_if_t<std::is_integral_v<T> && std::is_unsigned_v<T>>>
^^^^^
MyClass& MyClass::operator&=(T d)
When the condition std::is_integral_v<T> && std::is_unsigned_v<T>
is true, enable_if::type
is void
. Without class
void
is treated as non-type template parameter what is wrong (void
cannot be used as non-type parameter reference).
By using class
/typename
the second parametr is defined as type parameter which takes void - class SomeTypeName = void
if the condition in enable_if is true, or this function template is discarded from overloads set when enable_if's condition is false.