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

C++构造函数的成员初始化器能否包含对其他成员的初始化操作?

C++构造函数的成员初始化器能否包含对其他成员的初始化操作?

这确实是个挺有意思的C++语法细节问题,咱们先看看你给出的代码例子:

#include <memory>  

struct A {
    int i, j;
    constexpr A() : i((std::construct_at(&j, 2), j-1)) {}
};

constexpr A a{};
static_assert(a.i == 1);
static_assert(a.j == 2);

这段代码的逻辑很巧妙:在A的constexpr构造函数里,成员i的初始化器用逗号表达式做了两件事——先用std::construct_at显式初始化成员j为2,再用j-1的值来初始化i,最后通过static_assert验证i是1、j是2。

那这种写法到底合不合法呢?咱们拆解着看:

首先,C++里有个关键规则:类成员的初始化顺序是按照它们在类中声明的顺序来的,和初始化列表里的顺序无关。这里i在j之前声明,正常情况下初始化i的时候,j还没被初始化,直接访问j属于未定义行为。但这里用了std::construct_at主动在i的初始化过程中构造j,情况就不一样了。

std::construct_at的作用是在指定的内存地址显式构造对象,这里&j指向的是j成员的内存空间——这个空间已经被分配好了,只是还没到它的初始化步骤。当我们调用std::construct_at(&j, 2)时,相当于提前完成了j的初始化,j的生命周期正式开始,这时候再读取j的值就是完全合法的了。

从实践情况来看,你提到的GCC、MSVC都能正确编译这段代码,并且通过static_assert的验证,这也符合我们对标准规则的理解:只要显式构造操作是合法的(内存有效、符合对象构造的要求),这种在一个成员的初始化器里提前初始化另一个成员的写法是被允许的。

备注:内容来源于stack exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:54:37