【发布时间】:2015-04-27 08:49:46
【问题描述】:
我在玩一些无用的代码来理解成员引用的初始化,结果碰到了这个:
struct A {};
struct B
{
B() : a()
{
}
const A& a;
};
上面的代码在使用 gcc 4.9.2 编译时出现以下错误:
In constructor 'B::B()':
error: value-initialization of reference type 'const A&'
B() : a()
我明白了。
但是如果我在 B 的构造函数的初始化列表中使用统一初始化,像这样:
struct A {};
struct B
{
B() : a{}
{
}
const A& a;
};
它编译得很好。
那么问题来了,为什么这里使用统一初始化会改变编译结果呢?
我也在 Microsoft Visual C++ 2013 中尝试过。 它不会编译任一版本的代码,并显示相同的错误消息:
Error 3 error C2440: 'initializing' : cannot convert from 'int' to 'const A &
你可以在这里快速玩一下:
【问题讨论】:
-
统一初始化是一个相对较新的特性,你必须预料到它会出现一些编译器错误。在这种情况下,不查,我猜微软的编译器是正确的。
-
我的猜测:
{}被解释为对A的默认构造函数的调用(就像你做了A a {};一样),所以创建了一个临时的A{}。然后它被绑定到 const-ref 并延长它的生命周期(就像你做了const A & a {},它也适用于 GCC)。但我不知道标准对此有何规定;如果允许的话……真正让我困惑的是,MSVC 看到了一个我看不到的int……你真的编译了这段代码吗? -
@JamesKanze 我明白这一点,但我不想只是出去大喊编译器错误。也许有一些关于统一初始化的东西我不知道,这会使它在这种情况下表现不同。
-
@5gon12eder,这就是我的想法,直到我看到这个stackoverflow.com/questions/2784262/…。请参阅标准中的引述:在构造函数的 ctor-initializer (§12.6.2 [class.base.init]) 中临时绑定到引用成员会持续存在,直到构造函数退出。不完全确定如何解释。
-
@5gon12eder 标准过去常说引用的列表初始化总是创建一个临时的并且从不直接绑定。这就是链接问题中 GCC 问题的原因(当引用可以直接绑定时,创建一个临时的没有意义)并且已由 CWG1288 修复。临时生命周期问题是不同的。
标签: c++ gcc reference initialization initializer-list