C++:需要帮助理解运算符重载错误

Ida*_*yev 3 c++ operator-overloading operators c++11

我得到了这个代码:

1 #include <iostream>
2 using namespace std;
3
4 class B {
5 private:
6      int n;
7 public:
8      B(int x) : n(x) {}
9      B operator +(B& b) {
10         return B(n+b.n);
11     }
12     friend ostream& operator <<(ostream &out, const B& b) {
13         out << "B: " << b.n;
14         return out;
15     }
16     bool operator <(const B& rhs) const{
17         return n < rhs.n;
18     }
19 };
20
21 B smaller (const B& b1, const B& b2) {
22     if(b1 < b2)
23         return b1;
24     else
25         return b2;
26 }
27
28 int main() {
29     B b1(1), b2(2), b3(3);
30     const B b4 = b1 + (b2 + b3);
31     cout << smaller(b1,b2) << endl;
32     return 0;
33 }

Run Code Online (Sandbox Code Playgroud)

我被要求指出错误(解释它们)并提供修复,在找到两个并修复它们之后我得到了上面的代码。

当尝试在 Visual Code 上编译它时,我注意到第 30 行在我不明白原因的情况下给出了一个错误。我得到的错误是:

不匹配“operator+”(操作数类型为“B”和“B”)

不能将“B&”类型的非常量左值引用绑定到“B”类型的右值

在 google 上搜索并没有发现任何东西后,我尝试了各种方法,包括在第 9 行(运算符 +)的参数中添加一个常量来解决问题。我仍然不明白是什么问题,我想得到一个解释。

谢谢你。

joh*_*ohn 7

结果(b2 + b3)暂时的。也就是说,它是一个类型的对象,B作为执行较大表达式的一部分而被创建和销毁。

C++ 有一条规则,即不能将非常量引用绑定到临时引用。但这正是您的代码试图做的。因此需要const。

顺便说一句,您的重载运算符的正确签名是

class B
{
    B operator +(const B& b) const {
        ...
    }
};
Run Code Online (Sandbox Code Playgroud)

方法和参数都应该是const。

更好的是让 operator+ 成为非会员

B operator +(const B& a, const B& b) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

多读一些。

  • @user是的,这样编译器就会平等对待operator+的两个参数。如果operator+是成员,那么第一个参数将与第二个参数区别对待,特别是编译器不会对第一个参数应用任何自动类型转换。 (3认同)
  • @user 对于上面的代码,例如 `b + 2` 将使用编译器使用 `B(int)` 构造函数进行编译,从 2 创建一个 `B` 对象。但是使用 `operator+` 作为成员函数 `2 + b` 将无法编译,因为编译器在这种情况下不会应用类型转换。使用“operator+”作为非成员函数,两种情况都可以编译。 (2认同)