我目前正在尝试了解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}
,这里将进行详尽的解释。