ISO C++说这些是模糊的,运算符重载

Col*_*ion 1 c++ overloading ambiguous operator-keyword

当我写一些关于基本运算符重载的代码时.我发现了这段代码,

struct MyInt {
  public:
    MyInt()  : data() { };

    MyInt(int val) : data(val) { }

    MyInt& operator++() {
      ++data;

      return (*this);
    }

    MyInt operator++(int) {
      MyInt copy = *this;
      ++data;

      return copy;
    }

    MyInt& operator+=(const MyInt& rhs) {
        data += rhs.data;
        return *this;
    }

    MyInt operator+(const MyInt& rhs) const {
      MyInt copy = *this;
      copy += rhs;

      return copy;
    }

    int data;
};
Run Code Online (Sandbox Code Playgroud)

这些都很好,直到我在课程声明后添加它

MyInt operator+(const MyInt& lhs, const MyInt& rhs)
{
  MyInt copy = lhs;
  copy.data += rhs.data;

  return copy;
}
Run Code Online (Sandbox Code Playgroud)

有了这个主要声明

int main () {
  MyInt mi = 10;
  MyInt mi2 = 11;
  MyInt mi3 = mi++ + ++mi2;

  mi3 += mi2;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译时,g ++向我发出了这个警告

warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
   MyInt mi3 = mi++ + ++mi2;
                        ^
note: candidate 1: MyInt operator+(const MyInt&, const MyInt&)
 MyInt operator+(const MyInt& lhs, const MyInt& rhs)
       ^
note: candidate 2: MyInt MyInt::operator+(const MyInt&) const
     MyInt operator+(const MyInt& rhs) const {
Run Code Online (Sandbox Code Playgroud)

从我看到的其他问题来看,它们都是错误而不是警告.所以我不确定为什么代码仍然有效.希望有人可以向我解释为什么会发生这种情况.

提前致谢.

Pet*_*ker 7

有一个成员函数operator+(const MyInt&) const,可以像这样调用:

MyInt m1;
MyInt m2;
m1 + m2;
Run Code Online (Sandbox Code Playgroud)

还有一个免费的功能operator+(const MyInt&, const MyInt&),可以像这样调用:

MyInt m1;
MyInt m2;
m1 + m2;
Run Code Online (Sandbox Code Playgroud)

这就是编译器抱怨的原因:语言定义说没有办法决定使用哪一个.选择一个或另一个.

通常的惯例是只有自由函数,并通过调用实现它operator+=.

警告告诉您接受代码是gcc扩展.在形式上,编译器不需要拒绝编译错误的代码.唯一的要求是他们发出了一个gcc所做的诊断.完成后,可以继续以编译器编写者认为合理的某种方式编译代码.依赖此类扩展的代码不可移植.