c++ - 在 C++ 中,您需要在两个方向上重载 operator== 吗?
问题描述
假设我正在与一个班级一起工作:
class Foo{
public:
std:string name;
/*...*/
}/*end Foo*/
我为operator==
bool operator==(const Foo& fooObj, const std::string& strObj) {
return (fooObj.name == strObj);
}
我是否还需要反向重新实现相同的逻辑?
bool operator==(const std::string& strObj, const Foo& fooObj) {
return (strObj == fooObj.name);
}
解决方案
(C++20 以后)
随着p1185被 C++20 接受,您不需要提供多个重载。该论文对标准进行了这些更改(其中包括):
[over.match.oper]
3.4 - [...] 对于
!=
运算符 ([expr.eq]),重写的候选者包括运算符的所有成员、非成员和内置候选者==
,(x == y)
当上下文转换为使用该运算符的布尔值==
。对于等式运算符,重写的候选还包括一个合成候选,两个参数的顺序颠倒,对于每个成员、非成员和内置候选,==
重写表达式(y == x)
在上下文中是格式正确的使用该运算符转换为 bool==
. [注意:从成员候选中合成的候选将其隐式对象参数作为第二个参数,因此第一个参数考虑隐式转换,但不考虑第二个参数。— 尾注] [...]8 [...] 如果通过重载决议为
!=
运算符选择了重写的候选者,则将其x != y
解释为(y == x) ? false : true
所选择的候选者是具有相反参数顺序的合成候选者,或者(x == y) ? false : true
以其他方式使用所选的重写operator==
候选者。如果通过重载决议为==
运算符选择了重写的候选者,则将x == y
其解释为(y == x) ? true : false
使用选定的重写operator==
候选者。
以上意味着您不仅不需要向操作员提供操作数颠倒的顺序,还可以!=
免费获得!此外,operator==
如果有意义,该函数可以成为成员。虽然正如上面第一段中的注释所说,它是一个成员或自由函数会影响隐式转换,所以你仍然需要记住这一点。
(最高 C++17)
如果你想支持字符串在左边和Foo
右边的比较,你可以这样做。实现不会将参数重新排序为重载operator==
以使其工作。
但是,您可以避免重复实现的逻辑。假设您的操作员应按预期运行:
inline bool operator==(const std::string& objA, const Foo& objB) {
return objB == objA; // Reuse previously defined operator
}
推荐阅读
- android - Android PorterDuff:为什么 PorterDuff.Mode.SRC_IN 不删掉其余的源代码?
- c++ - 对临时对象的 const 引用不会延长其生命周期
- r - 创建具有多个对象和每个对象多个观察值的汇总数据集
- json - 不要将任何重复值输出到 csv 文件
- python - 如何回答是和否问题 paramiko
- python - 将 AWS CLI 命令转换为 Python AWS Lambda 函数
- sql - 卡在oracle中的查询
- nginx - 在 Heroku 中部署应用程序时如何解决 502 Bad Gateway 错误
- python - Pyspark - Looping through structType and ArrayType to do typecasting in the structfield
- assembly - 无法使用 VGA 下划线位置寄存器设置下划线位置