错误:“operator==”的重载不明确

error: ambiguous overload for ‘operator==’

本文关键字:重载 不明确 错误 operator      更新时间:2023-10-16

我试图理解为什么我的c++编译器与以下代码混淆:

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;
}

编译导致:

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

我知道我可以通过提供明确的operator==:来解决症状

  bool operator==(Enum const &rhs) { return t_ == rhs.t_; }

但我真正想要的是解释为什么只有在class中比较enum才会导致歧义。我写了这个小的枚举包装器,因为我被要求在代码中只使用C++03。

调用不明确,因为Enum::Typeint版本都通过一个隐式转换有效,前者使用operator Type转换,后者使用operator T模板转换运算符。

目前尚不清楚为什么要转换为任何类型,但如果删除该运算符,代码就会工作。

如果您使用的是C++11,那么应该使用作用域枚举。

Enum是实现定义的积分类型,主要是int。现在,无论您为enum实现什么运算符,都与您为类型int实现运算符一样。并重新定义了intdoublechar等积分类型的任意算子。。。是不允许的,因为这将改变编程语言本身的基本含义。

enum可以隐式转换为int(据我所知,这是由于与C的向后兼容性造成的。如果可以使用C++11,则可以使用enum class来解决此问题,因为作用域枚举不允许隐式转换到int