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.
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.
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