此问题与以下转载的代码段有关:
struct A {
A():b(0) { }
A(const A&, int b = 0):b(b) { }
int b;
};
int main() {
A a;
const A& a1 = { a };
const A& a2 = { a, 1 };
a.b = 2;
std::cout << a1.b << a2.b << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
分配a1的右侧可以是构造中的单个值或构造的参数列表.标准中是否有任何指定哪种解释优先?对于a2,它是一个临时A的结构,如果我没有误解,它的地址被分配给a2.
顺便说一句,在Coliru中用clang ++编译这段代码就产生了输出21. gcc ++ - 4.8输出01.
自从缺陷报告发布C++ 11标准以来,列表初始化的定义已经发生了很大的变化.
从草案n3485开始(在标准发布之后,有一些更正,但没有C++ 1y功能)[dcl.init.list]/3
对象或类型引用的列表初始化
T
定义如下:
- 如果
T
是聚合[...]- 否则,如果初始化列表没有元素[...]
- 否则,如果
T
是std::initializer_list<E>
[...] 的专业化- 否则,如果
T
是类型[...]- 否则,如果初始化列表具有单个元素类型
E
且且T
不是引用类型或其引用类型与引用相关E
,则从该元素初始化对象或引用; 如果将元素转换为需要缩小转换T
,则程序格式错误.- 否则,如果
T
是引用类型,则引用的类型的prvalue临时T
是列表初始化的,并且引用绑定到该临时- [...]
在委员会的github repo(ce016c64dc)的最新草案中,这里只有一点点改动[dcl.init.list]/3:
- 否则,如果
T
是引用类型,则引用类型的prvalue临时值T
是copy-list-initialized或direct-list-initialized,具体取决于引用的初始化类型,并且引用绑定到该临时值.
从草案n3242(标准之前)[dcl.init.list]/3:
对象或类型引用的列表初始化
T
定义如下:
- 如果初始化列表没有元素[...]
- 否则,如果
T
是聚合[...]- 否则,如果
T
是std::initializer_list<E>
[...] 的专业化- 否则,如果
T
是类型[...]- 否则,如果
T
是对类类型的引用或者T
是任何引用类型且初始化列表没有元素,则引用的类型的prvalue临时值T
是列表初始化的,并且引用绑定到该临时类型.- [...]
(我现在没有标准本身的副本.)
假设您的编译器实现了针对缺陷报告的建议解决方案.然后,第一个例子
const A& a1 = { a };
Run Code Online (Sandbox Code Playgroud)
初始化像const A& a1 = a;
(没有临时); 和第二个例子
const A& a2 = { a, 1 };
Run Code Online (Sandbox Code Playgroud)
初始化像const A& a2 = A(a,1);
.