由于缺陷报告,自 C++11 标准发布以来,列表初始化的定义发生了相当大的变化。
来自草案 n3485(标准发布后,有一些更正但没有 C++1y 特性)[dcl.init.list]/3
类型的对象或引用的列表初始化T
定义如下:
- 如果
T
是一个聚合 [...]
- 否则,如果初始化列表没有元素 [...]
- 否则,如果
T
是std::initializer_list<E>
[...]
- 否则,如果
T
是类类型 [...]
- 否则,如果初始化列表有一个类型的元素
E
并且T
不是引用类型或其引用类型与引用相关E
,则从该元素初始化对象或引用;如果需要进行缩小转换以将元素转换为T
,则程序格式错误。
- 否则,如果
T
是引用类型,则所引用类型的纯右值临时T
被列表初始化,并且引用绑定到该临时
- [...]
在委员会的 github 存储库 (ce016c64dc) 的最新草案中,此处仅对一点 [dcl.init.list]/3 进行了轻微更改:
- 否则,如果
T
是引用类型,则所引用类型的纯右值临时T
是复制列表初始化或直接列表初始化,具体取决于引用的初始化类型,并且引用绑定到该临时。
来自草案 n3242(在标准之前)[dcl.init.list]/3:
类型的对象或引用的列表初始化T
定义如下:
- 如果初始化列表没有元素 [...]
- 否则,如果
T
是一个聚合 [...]
- 否则,如果
T
是std::initializer_list<E>
[...]
- 否则,如果
T
是类类型 [...]
- 否则,如果
T
是对类类型的引用,或者如果T
是任何引用类型并且初始化列表没有元素,则引用类型的纯右值临时T
是列表初始化的,并且引用绑定到该临时。
- [...]
(我现在没有标准本身的副本。)
假设您的编译器实现了对缺陷报告的建议解决方案。然后,第一个例子
const A& a1 = { a };
初始化为const A& a1 = a;
(非临时);第二个例子
const A& a2 = { a, 1 };
初始化为const A& a2 = A(a,1);
.