如果第二个参数是右值,则重载 != 运算符不起作用



我目前正在尝试了解C++运算符重载。我尝试在以下代码中重载运算符"!=":

#include <iostream>
using namespace std;
class MyClass{
int a=0;int b=0;
public:
MyClass() = default;
MyClass(int x,int y){a = x;b=y;}
MyClass(const MyClass& ob){a = ob.a;b = ob.b;}
MyClass& operator=(const MyClass& ob) = default;
bool operator!=(const MyClass& ob){
return a!=ob.a && b!=ob.b;
}
};
int main() {
MyClass ob{112,981};

/* This Works
MyClass ob2{211,121};
if(ob!=ob2){ */

/*This also works
if(ob.operator!=({211,121})){ */

//Why does this does not work ??
if(ob!={211,121}){
cout<<"Operator != overloaded"<<endl;
}
return 0;
}

在 main 函数中,if(ob!={211,121}){...}不起作用并导致以下编译错误:

prog.cpp: In function ‘int main()’:
prog.cpp:25:9: error: expected primary-expression before ‘{’ token
if(ob!={211,121}){
^
prog.cpp:25:9: error: expected ‘)’ before ‘{’ token

此外,令我惊讶的是,当我尝试以下变体来实现相同的逻辑时,它起作用了:

if(ob.operator!=({211,121})){
return a!=ob.a && b!=ob.b;
}

有人可以解释一下原因吗?

https://godbolt.org/z/9WKf3f97Y

编译器告诉你。例如,海湾合作委员会说:

$ g++ -std=c++17 source.cpp && ./a.out
source.cpp: In function ‘int main()’:
source.cpp:24:12: error: expected primary-expression before ‘{’ token
24 |     if(ob!={211,121}){
|            ^
source.cpp:24:12: error: expected ‘)’ before ‘{’ token
24 |     if(ob!={211,121}){
|       ~    ^
|            )

而Clangd(我在IDE中使用它)直截了当

Initializer list cannot be used on the right hand side of operator '!=' [init_list_bin_op]

所以你根本做不到something != {init list}.请注意,在更简单的情况下也是如此:

int x = {}; // ok
x != {};    // not ok

请注意,这与 rhs 无关!=是右值。确实ob != MyClass{211,121}有效,MyClass{211,121}是一个正确的值。

至于为什么ob.operator!=({211,121})工作正常,那是因为它是对operator!=成员函数的函数调用,众所周知,该函数需要const MyClass&{211,121}可以转换为该函数。

关于为什么在操作员之后禁止{init-list},这里将进行详尽的解释。

最新更新