C++20默认实现的虚operator<=>是否会额外生成虚operator==?
问题1:默认实现的虚operator<=>隐式生成虚operator==是否符合标准
该行为是C++20标准强制规定的,不属于编译器自定义的实现惯例。
根据C++20标准的比较运算符统一规则:当用户为类显式默认声明operator<=>时,编译器会自动隐式声明一个匹配的operator==,该隐式声明的运算符会完全继承operator<=>的cv限定符、异常说明符、虚属性等所有声明特性。示例中将operator<=>声明为virtual,隐式生成的operator==自然也带有virtual属性,因此可以在子类中被重写。
struct A { virtual std::strong_ordering operator<=>(const A &) const = default; }; struct B : A { // 可以成功重写编译器隐式生成的虚operator==,符合标准规则 virtual bool operator==(const A&) const noexcept override; };
问题2:consteval虚函数示例的合法性判断
该程序本身存在不合法点,同时编译器的崩溃/错误运行行为也属于实现缺陷。
- 程序本身的问题:
consteval声明的是即时函数,所有对它的调用必须处于常量表达式上下文,在编译期完成求值,不允许存在运行时调用。示例中main函数的return语句return (a <=> a) == 0;属于运行时求值上下文,此处调用consteval修饰的operator<=>不符合语法规则,属于不合法程序。 - 编译器的问题:按照C++标准要求,对于不合法的程序,编译器应当输出明确的诊断信息(编译错误提示),但Clang直接崩溃、GCC直接生成运行错误的二进制文件的处理方式,属于编译器的实现bug。
#include <compare> struct A { virtual consteval std::strong_ordering operator<=>(const A &) const = default; }; struct B : A { virtual consteval bool operator==(const A&) const noexcept override { return false; } }; int main() { static constexpr B b; static constexpr const A & a = b; static_assert( (a <=> a) == 0 ); static_assert( a != a ); // 此处为运行时上下文,调用consteval函数属于语法错误 return (a <=> a) == 0; }
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

