C++20的比较运算符是否可以在类定义之外进行默认化?
结论
Clang的行为符合C++标准,GCC此处属于非标准的实现放宽,不符合标准要求。
标准依据
根据C++20标准 [class.compare.default] 章节第一条的明确规定:平等比较运算符 operator== 的默认化声明,必须出现在类定义内部,且必须是该运算符的第一个声明。
你给出的示例代码中,仅在类A的定义内声明了友元operator==,将= default默认化声明放到了类定义外,本身就违反了标准的强制要求,因此Clang抛出的错误是完全合规的。
如果你给GCC添加-pedantic-errors编译参数强制严格符合标准,GCC同样会抛出和Clang一致的错误。
类外定义的替代方案
你提到的将比较运算符实现放在类外、仅存在于单个翻译单元的需求是合理的,可以通过手动实现运算符达到同样效果,不需要依赖默认化语法:
// 类内声明 struct A { int x; friend bool operator==(A,A); }; // 类外实现,仅存在于当前翻译单元 bool operator==(A a, A b) { return a.x == b.x; // 结构成员无填充的场景也可以直接用memcmp }
手动实现的效果和默认生成的运算符完全一致,同样可以达到提升大型项目编译速度的目的。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

