c++ - ISO C++ 说这些是模棱两可的,运算符重载

标签 c++ overloading operator-keyword ambiguous

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

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

这些都很好,直到我在类声明之后立即添加它

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

  return copy;
}

有了这个主要声明

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

  mi3 += mi2;
}

当我尝试编译时,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 {

从我看到的其他问题来看,都是errors而不是warning。所以我不太确定为什么它的代码仍然有效。希望有人能向我解释为什么会这样。

提前致谢。

最佳答案

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

MyInt m1;
MyInt m2;
m1 + m2;

还有一个免费函数operator+(const MyInt&, const MyInt&),可以这样调用:

MyInt m1;
MyInt m2;
m1 + m2;

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

通常的约定是只有free函数,通过调用operator+=来实现。

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

关于c++ - ISO C++ 说这些是模棱两可的,运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35158878/

相关文章:

java - 不能使用 == 代替一元 & 来检查两个值是否相等

c++ - 单击时 QML 更改 View

c++ - 在 C++ 中重载子类中的方法

c++ - 在 Armadillo 中捕获 LAPACK 错误

c++ - 什么接口(interface)会将 cstrings、数组和其他类型复制到相同类型的实例?

typescript - TypeScript 的 core.ts 是如何构建而不会出现过载错误的?

javascript - 带对象的展开运算符

c++ - 这个加法类会不会导致内存泄露?

c++ - 初始化 dll 之间共享的变量

c++ - 是否可以使用相同的基类从另一个派生对象访问派生对象?