C++中哪些运算符可隐式定义或生成其他运算符?
C++运算符自动生成规则解答
问题1:为什么operator<=>不会生成operator==?
这是C++标准刻意设计的规则,核心原因有两个:
- 性能优先考量:相等性判断往往可以比三路比较有更高的优化空间。比如字符串类型的
operator==可以先对比两个字符串的长度,长度不一致直接返回false,而operator<=>必须逐字符比较到第一个不同的位置才能得出结果。如果允许自定义的operator<=>自动生成operator==,会默认引入不必要的性能开销。 - 语义独立性需求:部分场景下相等性判断和三路比较的语义存在天然差异,最典型的就是浮点数的NaN值,
NaN == NaN的结果是false,但三路比较中NaN <=> NaN会返回无序状态。标准不绑定自定义operator<=>和operator==的生成逻辑,是为了避免生成不符合业务预期的相等判断逻辑。
只有当你显式将operator<=>声明为= default时,编译器才会同步自动生成默认的operator==,自定义实现的operator<=>不会触发operator==的生成,这就是你的测试代码编译报错的原因。如果要修复你的测试代码,只需要在类中补充一行bool operator==(const Foo&) const = default;即可。
问题2:完整的运算符自动生成规则是什么?
C++标准仅对比较类运算符开放了隐式自动生成的规则,算术运算符、位运算符、赋值运算符等其他运算符都不存在任何隐式自动生成的逻辑,你测试的“operator+和一元operator-自动生成二元operator-”的规则并不存在。
目前所有比较运算符的自动生成规则如下:
- 只要你显式定义了
operator==(包括声明为= default),编译器就会自动生成对应的operator!= - 如果你显式将
operator<=>声明为= default,编译器会自动生成默认的operator==,同时生成<、>、<=、>=四个关系运算符 - 如果你自定义实现了
operator<=>,编译器仅会自动生成<、>、<=、>=四个关系运算符,不会生成operator== - 所有自动生成的运算符都支持正反参数顺序的调用,只要参数类型兼容即可。
你之前查阅的默认比较规则文档已经涵盖了所有可隐式生成的运算符规则,不存在其他未公开的自动生成逻辑。
内容的提问来源于stack exchange,提问作者Maurycyt
相关产品推荐
相关产品推荐

