Enum class and global operator ~ overload

Consider the following code:

struct D { template <class T> D (T); }; int operator~(const D &); template <typename T> T &make (); template <typename Rhs> struct H { static const int value = sizeof ~make<Rhs>(); }; enum class E; int main () { return H<E>::value; } 

Is this valid C ++ 11?

Klang accepts this. Gcc gives an error message:

  % gcc -std=c++11 b.ii b.ii: In instantiation of 'const int H<E>::value': b.ii:16:28: required from here b.ii:11:35: error: no match for 'operator~' (operand type is 'E') static const int value = sizeof ~make<Rhs>(); 

The code has been reduced from the gcc bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60852

This is an unreduced test case:

 #include <boost/type_traits.hpp> #include <iostream> enum class E {}; int main() { std::cout << boost::has_complement<E>() << std::endl; } 
+6
source share
1 answer

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

+8
source

All Articles