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

C++标准中成员原地初始化与初始化列表的优先级规则及代码疑问

成员原地初始化与初始化列表的优先级规则

首先直接给你明确答案:在C++11及之后的标准中,构造函数的初始化列表优先级高于成员的原地初始化,这个规则在C++标准的[class.base.init]章节(类基类初始化相关部分)有明确规定。

具体规则细节

当类的构造函数在初始化列表中显式初始化某个非静态数据成员时,该成员的原地初始化表达式会被直接忽略,完全不会执行。换句话说,初始化列表的显式初始化是“覆盖”了原地初始化的——这不是歧义,是标准明确划定的优先级顺序。

对你的示例代码的分析

看你写的Baz结构:

struct Baz {
    Baz() : foo(5.0f) {} // 初始化列表显式初始化foo
    Bar bar;
    Foo foo = Foo(3);    // 原地初始化,会被忽略
    Bar bar2;
};

当你在main里创建Baz baz时,执行流程是这样的:

  1. 执行Baz的构造函数,优先处理初始化列表里的foo(5.0f),调用Foo的float版本构造函数,完全跳过foo = Foo(3)这个原地初始化代码。
  2. 然后按类成员的声明顺序,初始化bar和bar2(它们用默认构造函数完成初始化)。

所以你的代码里Foo(3)根本没被调用,自然不会抛出std::runtime_error,程序能正常运行。

关于编译器警告的问题

Visual Studio 2017没给出警告,是因为这是标准允许的合法行为,不属于编译错误。不过有些编译器支持额外的警告选项来提醒这种“原地初始化被覆盖”的情况,比如Clang的-Winitializer-overrides,但VS2017默认没开启这类警告,你可以去编译器的警告设置里找找类似的选项来开启提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:18:08