Reputation: 12530
I am trying to understand why my c++ compiler is confused with the following piece of code:
struct Enum
{
enum Type
{
T1,
T2
};
Enum( Type t ):t_(t){}
operator Type () const { return t_; }
private:
Type t_;
// prevent automatic conversion for any other built-in types such as bool, int, etc
template<typename T> operator T () const;
};
enum Type2
{
T1,
T2
};
int main()
{
bool b;
Type2 e1 = T1;
Type2 e2 = T2;
b = e1 == e2;
Enum t1 = Enum::T1;
Enum t2 = Enum::T2;
b = t1 == t2;
return 0;
}
Compilation leads to:
$ c++ enum.cxx
enum.cxx: In function ‘int main()’:
enum.cxx:30:10: error: ambiguous overload for ‘operator==’ (operand types are ‘Enum’ and ‘Enum’)
b = t1 == t2;
^
enum.cxx:30:10: note: candidates are:
enum.cxx:30:10: note: operator==(Enum::Type, Enum::Type) <built-in>
enum.cxx:30:10: note: operator==(int, int) <built-in>
I understand that I can solve the symptoms by providing an explicit operator==
:
bool operator==(Enum const &rhs) { return t_ == rhs.t_; }
But really what I am looking for is the interpretation of why comparing enum
leads to an ambiguity only when it's done within a class
. I wrote this small enum wrapper since I am required to only use C++03 in my code.
Upvotes: 5
Views: 1476
Reputation: 10136
enum
can be implicitly converted to int
(as far as I understand it is caused by backward compatibility to C
. If you can use C++11
you can use enum class
to solve this issue because scoped enums do not allow implicit conversion to int
.
Upvotes: 0
Reputation: 997
Enum
is implementation defined integral type which is mostly int
. Now whatever operator you implement for enum
is like you are implementing operator for type int
. And redefining the any operator for integral types such as int
, double
, char
... is not allowed as it will change basic meaning of the programming language itself.
Upvotes: 0
Reputation: 65770
The call is ambiguous as both the Enum::Type
and int
versions are valid with a single implicit conversion, the former using the operator Type
conversion and the latter using the operator T
template conversion operator.
It is unclear why you have a conversion to any type, but if you remove that operator, the code works.
If you are using C++11 you should use scoped enums instead.
Upvotes: 2