列表初始化const对临时对象的引用

时间:2013-06-29 17:20:26

标签: c++ c++11

我发现下面的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,这样的行为是否正确标准?请指出标准的相关部分。

注意: AB以及它们绑定的临时实例都在表达式中实例化。在表达结束时,它们被破坏,以及它们绑定的临时性,这就是为什么它们的生命时间应该与临时生命时间相同。

编辑:标准的这一部分是否可以解释2次初始化之间的差异:

  

- 否则,如果T是引用类型,则由T引用的类型的prvalue临时列表被初始化,   并且引用绑定到那个临时的。 [注意:像往常一样,绑定将失败并且程序   如果引用类型是非const类型的左值引用,则格式错误。 - 结束说明]

2 个答案:

答案 0 :(得分:4)

这种行为是不正确的。见8.5.4p3最后一个项目。一段时间以前的预标准草案就是这种情况,但在C ++ 11中并非如此。

看起来你很困惑:在任何情况下都不应该创建一个临时的。两种情况都应该用另一个引用初始化引用。仅在第二种情况下,一些预标准草案表示应创建临时值并绑定到成员引用,而不是直接初始化引用。

(参见this list中的第27号)。

答案 1 :(得分:2)

  

我发现,对于第一个示例,绑定的临时对象在A的实例的生命周期中持续存在,但对于B的实例不是这种情况。根据C ++ 11,这样的行为是否正确标准?

B的行为是正确的。但是A的行为是错误的,因为临时的生命期不应该持续到A的对象的生命期(或者生命周期)在B)的情况下B

但作为旁注,由于您将临时绑定到B的成员,请注意!当构造函数返回时,临时不存在,这意味着成员引用的内容不存在!