malat
malat

Reputation: 12530

error: ambiguous overload for ‘operator==’

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

Answers (3)

Alex
Alex

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

rahul.deshmukhpatil
rahul.deshmukhpatil

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

TartanLlama
TartanLlama

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

Related Questions