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?
Clang accepts it. Gcc gives an error:
% 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 was reduced from a gcc bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60852
This is the unreduced test case:
#include <boost/type_traits.hpp>
#include <iostream>
enum class E {};
int main()
{ std::cout << boost::has_complement<E>() << std::endl; }
GCC is right here, scoped enumeration, aka enum class
are not implicitly converting to int or anything else. By extension, they do not have a built-in operator~
, so you need to cast explicitly :
#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 give the good error. It is a bug clearly as operator~(D)
is 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>();
The rules about collecting the overloads § 13.3.1.2 :
For a unary operator @ with an operand of a type whose cv-unqualified version is T1, [...], three sets of candidate functions, designated member candidates, nonmember candidates and built-in candidates, are constructed as follows:
And the finish :
However, if no operand has a class type, only those non-member functions in the lookup set that have a first parameter of type T1 or reference to (possibly cv-qualified) T1”, when T1 is an enumeration type, [...], are candidate functions.
To summarize, because E is of non class type, only free function operators taking a E or a reference to E are considered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With