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

编译器默认生成的构造函数是否为constexpr?相关代码合规性问询

让我逐个解答你的问题:

问题1:编译器生成的构造函数默认是constexpr的吗?

不是无条件默认的——编译器只会在完全满足constexpr构造函数的所有要求时,才会将隐式生成的构造函数(比如默认构造、拷贝构造、移动构造)声明为constexpr。

以C++14标准为例,隐式生成的默认构造函数被标记为constexpr的前提是:

  • 所有直接基类的默认构造函数都是constexpr;
  • 每个非静态数据成员的默认构造函数(如果有的话)都是constexpr;
  • 构造函数本身满足constexpr构造函数的其他规则(比如函数体是=default、没有try块、不包含不允许的操作等)。

举两个直观的例子:

// 例1:满足所有条件,隐式默认构造函数是constexpr
struct Bar { constexpr Bar() = default; };
struct Foo { Bar b; };
constexpr Foo f; // 合法,因为Foo的默认构造是constexpr

// 例2:不满足条件,隐式默认构造函数不是constexpr
struct Baz { int x; };
// constexpr Baz b; // 非法,因为int的默认初始化无法在常量表达式中产生确定值,Baz的默认构造不是constexpr

问题2:这段代码的编译行为是否符合C++14标准?

是的,clang++ 3.8.0和g7.2.0的编译行为完全符合C14标准,哪怕给Foo添加int i;这类成员也一样。我们来拆解原因:

首先看代码:

struct Foo { constexpr operator bool() const { return false; } };
int main() { constexpr bool b = Foo{}; (void)b; }

核心逻辑是用Foo{}(临时Foo对象)初始化constexpr bool b,这要求整个转换过程是常量表达式。我们分两步分析:

  1. Foo的隐式默认构造函数是否是constexpr?

    • 当Foo没有成员时:没有基类、没有非静态成员需要初始化,完全满足C++14对隐式constexpr构造函数的要求,所以默认构造是constexpr的,Foo{}可以在常量表达式中创建。
    • 当Foo添加int i;时:隐式生成的默认构造函数会对i做默认初始化,但C++14允许constexpr构造函数默认初始化内置类型——只要后续没有在常量表达式中读取这个未初始化的成员。而我们的转换运算符operator bool()根本没有访问i,所以这个构造过程依然符合常量表达式的要求。
  2. 转换过程是否是常量表达式?
    Foo的operator bool()被声明为constexpr,且函数体只是返回常量false,完全符合constexpr函数的规则。结合第一步中Foo{}是合法的常量表达式构造,整个Foo{} -> bool的转换过程属于常量表达式,因此可以用来初始化constexpr bool b。

综上,这段代码在C++14下是完全合规的,编译器的行为没有问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:27:38