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

删除默认构造函数与不编写默认构造函数的差异探究

C++空大括号初始化的构造函数匹配规则差异解析

要理解这三种场景的差异,核心在于C++标准对**空大括号初始化(列表初始化)**的优先级规则,以及默认构造函数的存在状态对初始化逻辑的影响:

1. 显式定义默认构造函数的场景

当类显式定义了默认构造函数(同时存在initializer_list构造函数)时,执行Obj o{};会触发C++标准中[dcl.init.list]/3.2的规则:

若初始化列表为空,且类类型拥有默认构造函数,则对象被值初始化,直接调用默认构造函数。

这条规则的优先级高于initializer_list构造函数的匹配逻辑,因此空大括号会优先调用默认构造函数,而非initializer_list构造函数。

2. 不定义默认构造函数的场景

如果类只定义了initializer_list构造函数,未显式声明默认构造函数,编译器不会生成隐式默认构造函数(C++标准规定:类存在任何用户声明的构造函数时,隐式默认构造函数不会被生成)。

此时执行Obj o{};,由于类没有默认构造函数,[dcl.init.list]/3.2的规则不适用,会进入[dcl.init.list]/3.4的构造函数重载决议阶段:

  • 候选构造函数只有initializer_list构造函数;
  • 空的初始化列表可以被解析为空的std::initializer_list参数,因此该构造函数可行,最终被调用。

3. 显式删除默认构造函数的场景

当显式删除默认构造函数(Obj() = delete;)时,该构造函数是已声明但不可用的状态,类仍然被视为“拥有默认构造函数”。

执行Obj o{};时,依然触发[dcl.init.list]/3.2的规则,尝试进行值初始化并调用默认构造函数,但由于该构造函数已被删除,编译器会直接抛出编译错误,不会进入initializer_list构造函数的匹配阶段。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:43:27