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

C++17如何调用空initializer_list构造函数及与C++14的差异

C14与C17下Foo({})行为差异解答

1. 行为不同的核心原因

这个差异来源于C++17引入的**强制拷贝消除(mandatory copy elision)**配套的初始化语义规则变更:

  • C++14的规则下,Foo({})只能被解释为「调用Foo的构造函数,传入一个由{}初始化的实参」。此时重载决议会匹配到形参为initializer_list<int>的构造函数:空花括号{}可以直接初始化出一个空的initializer_list<int>实例,符合构造函数的参数要求,因此输出init_list。
  • C17的规则新增了对T({args})形式的语义解释路径:如果T{args}是合法表达式,那么T({args})可以匹配到编译器自动生成的隐式拷贝/移动构造函数,相当于T(T{args})。由于C17强制要求拷贝消除,不需要实际调用拷贝/移动构造函数,整个表达式会直接优化为调用T{args}对应的构造函数。放到这个例子里,Foo{}是合法的默认构造调用,因此Foo({})被直接优化为默认构造调用,输出empty,这个路径的重载优先级高于匹配initializer_list构造函数的路径。

2. C++17下构造传入空initializer_list的Foo实例的方法

有三种常用的写法可以绕过默认构造的匹配优先级,强制调用initializer_list版本的构造函数:

  • 显式构造空的initializer_list<int>实例传入:
    Foo(std::initializer_list<int>{});
    
  • 传入双层空花括号,让编译器无法将其解释为构造Foo临时对象的初始化器:
    Foo({{}});
    
  • 使用列表初始化语法,列表初始化会优先匹配initializer_list构造函数:
    Foo{{}};
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:36:02