初始化列表中 const 引用成员的初始化
Initialization of const reference member in initializer list
我正在玩一些无用的代码来理解成员引用的初始化,并遇到了这个:
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 &
您可以在这里快速体验一下:
GCC 对 {}
的解释是正确的。 [dcl.init.list]/p3.8-9(引用 N4296;较早的草案对这两个项目符号具有相同的相对顺序):
List-initialization of an object or reference of type T
is defined as
follows:
[7 inapplicable bullets omitted]
Otherwise, if T
is a reference type, a prvalue temporary of the type referenced by T
is copy-list-initialized or
direct-list-initialized, depending on the kind of initialization for
the reference, and the reference is bound to that temporary. [ Note:
As usual, the binding will fail and the program is ill-formed if the
reference type is an lvalue reference to a non-const type. —end note
]
- Otherwise, if the initializer list has no elements, the object is value-initialized.
列表初始化引用命中项目符号 3.8,导致临时构造。 3.9 中的值初始化情况不适用。
引用的值初始化格式错误 ([dcl.init]/p9):
A program that calls for default-initialization or
value-initialization of an entity of reference type is ill-formed.
但是,从 N4296 开始,根据 [class.base.init]/p8:
A temporary expression bound to a reference member in a
mem-initializer is ill-formed.
这是由于 CWG issue 1696 而添加的,它是针对 C++14 的 DR(缺陷报告)。
Pre-CWG1696,标准规定(N4140 [class.temporary]/p5.1):
A temporary bound to a reference member in a constructor’s
ctor-initializer (12.6.2) persists until the constructor exits.
这意味着引用将在构建后立即变为悬挂。这可能促使 CWG1696 决定完全禁止此类绑定。
我正在玩一些无用的代码来理解成员引用的初始化,并遇到了这个:
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 &
您可以在这里快速体验一下:
GCC 对 {}
的解释是正确的。 [dcl.init.list]/p3.8-9(引用 N4296;较早的草案对这两个项目符号具有相同的相对顺序):
List-initialization of an object or reference of type
T
is defined as follows:
[7 inapplicable bullets omitted]
Otherwise, if
T
is a reference type, a prvalue temporary of the type referenced byT
is copy-list-initialized or direct-list-initialized, depending on the kind of initialization for the reference, and the reference is bound to that temporary. [ Note: As usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a non-const type. —end note ]- Otherwise, if the initializer list has no elements, the object is value-initialized.
列表初始化引用命中项目符号 3.8,导致临时构造。 3.9 中的值初始化情况不适用。
引用的值初始化格式错误 ([dcl.init]/p9):
A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed.
但是,从 N4296 开始,根据 [class.base.init]/p8:
A temporary expression bound to a reference member in a mem-initializer is ill-formed.
这是由于 CWG issue 1696 而添加的,它是针对 C++14 的 DR(缺陷报告)。
Pre-CWG1696,标准规定(N4140 [class.temporary]/p5.1):
A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
这意味着引用将在构建后立即变为悬挂。这可能促使 CWG1696 决定完全禁止此类绑定。