我发现下面的2个样本使用g ++ - 4.8.1获得不同的行为,当临时数据绑定到类的实例时:
template <class T>
struct A
{
A(T const& a) : b(a) { }
T const& b;
};
和
template <class T>
struct B
{
B(T const& a) : b{a} { }
T const& b;
}
我发现,对于第一个示例,绑定的临时对象在A的实例的生命周期中持续存在,但对于B的实例不是这种情况。根据C ++ 11,这样的行为是否正确标准?请指出标准的相关部分。
注意:
A
和B
以及它们绑定的临时实例都在表达式中实例化。在表达结束时,它们被破坏,以及它们绑定的临时性,这就是为什么它们的生命时间应该与临时生命时间相同。
编辑:标准的这一部分是否可以解释2次初始化之间的差异:
- 否则,如果T是引用类型,则由T引用的类型的prvalue临时列表被初始化, 并且引用绑定到那个临时的。 [注意:像往常一样,绑定将失败并且程序 如果引用类型是非const类型的左值引用,则格式错误。 - 结束说明]
答案 0 :(得分:4)
这种行为是不正确的。见8.5.4p3最后一个项目。一段时间以前的预标准草案就是这种情况,但在C ++ 11中并非如此。
看起来你很困惑:在任何情况下都不应该创建一个临时的。两种情况都应该用另一个引用初始化引用。仅在第二种情况下,一些预标准草案表示应创建临时值并绑定到成员引用,而不是直接初始化引用。
(参见this list中的第27号)。
答案 1 :(得分:2)
我发现,对于第一个示例,绑定的临时对象在A的实例的生命周期中持续存在,但对于B的实例不是这种情况。根据C ++ 11,这样的行为是否正确标准?
B
的行为是正确的。但是A
的行为是错误的,因为临时的生命期不应该持续到A
的对象的生命期(或者生命周期)在B
)的情况下B
。
但作为旁注,由于您将临时绑定到B
的成员,请注意!当构造函数返回时,临时不存在,这意味着成员引用的内容不存在!