GCC right here, scoped enumeration, aka enum class implicitly converted to int or something else. By extension, they do not have a built-in operator~ , so you need to explicitly specify:
#include <iostream> #include <type_traits> enum class E { val }; int main () { std::cout << ~std::underlying_type<E>::type(E::val); }
By removing your struct D and the global operator~ , clang gives a good error. This is a mistake, since operator~(D) not a candidate in the first place:
main.cpp:17:35: error: invalid argument type 'E' to unary expression static const int value = sizeof ~make<Rhs>();
Congestion collection rules ยง 13.3.1.2:
For a unary operator @ with an operand of type cv-unqualified version T1, [...] three sets of candidate functions, assigned candidate members that are not members of candidates and built-in candidates, are constructed as follows:
And the finish:
However, if none of the operands has a class type, only those who are not members of the function in the search set have the first parameter of type T1 or a reference to (possibly cv-qualified) T1 "when T1 is an enumeration of type, [ ...] are candidate functions.
To summarize, since E is of a nonclass type, only operators of a free function that accept E or refer to E. are considered
source share