You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

两个代码示例是否仅在C++23中合法,而在C++20中不合法?

关于C20与C23中默认constexpr比较运算符的合法性问题

在GCC 13.3出现回归问题后,我给程序中默认生成的太空船运算符添加constexpr时,发现不同编译器在C++20模式下处理相关代码存在差异。以下以相等比较运算符为例展示这些差异:

示例1

struct A {
    operator int() const;
};

struct B : A {
    constexpr bool operator==(const B &) const = default;
};
  • 编译表现:该代码可在Clang和MSVC中正常编译,但开启-pedantic-errors选项的GCC会报错:

error: call to non-'constexpr' function 'A::operator int() const' [-Winvalid-constexpr]

示例2

struct A {
    bool operator==(const A &) const;
};

struct B : A {
    constexpr bool operator==(const B &) const = default;
};
  • 编译表现:该代码仅能在MSVC中正常编译,开启-pedantic-errors选项的Clang也会报错:

error: defaulted definition of equality comparison operator that is declared constexpr but invokes a non-constexpr comparison function is a C23 extension [-Werror,-Wc23-default-comp-relaxed-constexpr]

问题解答

是的,这两个代码示例仅在C23中合法,在C20中均不合法,具体原因如下:

  • C20标准要求:默认声明为constexpr的比较运算符,其调用的所有子操作(包括基类的转换运算符、基类的比较运算符等)必须本身是constexpr的。如果依赖的子操作不满足constexpr要求,那么默认运算符的constexpr声明就违反了C20的规则。
  • C++23放宽了这一限制:默认的constexpr比较运算符允许调用非constexpr的子操作,仅要求在实际用于常量表达式计算的场景中,这些子操作能满足constexpr的要求即可(即声明阶段不强制依赖操作必须是constexpr,仅在常量上下文调用时才做校验)。

GCC和Clang开启-pedantic-errors后会严格遵循C20标准,因此触发报错;而MSVC可能默认启用了C23的扩展行为,或者对标准的实现更为宽松,所以允许编译通过。

内容的提问来源于stack exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:25:03