Amb*_*jak 5 c++ return reference temporary
考虑以下代码处理const引用:
const int & func (const int &x)
{
return x;
}
struct Foo {
Foo (const int &x)
: m_x(x) {}
const int & getX ()
{ return m_x; }
const int &m_x;
};
Run Code Online (Sandbox Code Playgroud)
我想知道现在允许以下哪些内容(如果有的话):
int x = func(int(7));
int y = Foo(int(7)).getX();
Run Code Online (Sandbox Code Playgroud)
是否保证临时int对象在赋值使用之前仍然存在或getX?
更新:所以看起来这是安全的 - 但为什么呢?
考虑存储指针而不是引用的边缘情况:
struct Foo {
Foo (const int &x)
: m_x(&x) {}
const int & getX ()
{ return *m_x; }
const int *m_x;
};
int y = Foo(int(7)).getX();
Run Code Online (Sandbox Code Playgroud)
似乎如果案例1)是正确的,这将是行不通的.但如果案例2)是正确的,它会.
两者都是安全的,因为您将值复制到x和y.临时表有效,直到完整表达结束.
4)有两种情况,临时在与完整表达结束时不同的地方被摧毁.第一个上下文是调用默认构造函数来初始化数组的元素.如果构造函数具有一个或多个默认参数,则在从构造函数返回后立即销毁在默认参数表达式中创建的任何临时值.
5)第二个上下文是指引用绑定到临时.绑定引用的临时对象或绑定引用的子对象的完整对象的临时对象在引用的生命周期内持续存在,除非下面指定.绑定到构造函数的ctor-initializer(12.6.2)中的引用成员的临时绑定将持续存在,直到构造函数退出.在函数调用(5.2.2)中与引用参数的临时绑定将持续存在,直到包含该调用的完整表达式完成为止.函数返回语句(6.6.3)中返回值的临时绑定将一直存在,直到函数退出.在所有这些情况下,在初始化引用的表达式的求值期间创建的临时值,除了引用所绑定的临时值之外,在创建它们的完整表达式的末尾以及与它们相反的顺序被销毁.完成他们的建设.如果引用的两个或更多临时工具的寿命在同一点结束,则这些临时工具在该点以与其构造完成相反的顺序被销毁.此外,对参考文献的临时性破坏应考虑到具有静态或自动存储期的物体的破坏顺序(3.7.1,3.7.2); 也就是说,如果obj1是在创建临时文件之前创建的具有静态或自动存储持续时间的对象,则在销毁obj1之前应该销毁临时文件; 如果obj2是在创建临时值后创建静态或自动存储持续时间的对象,则在销毁obj2之后应该销毁临时对象.[例如:
class C
{
/ / ...
public :
C();
C(int );
friend C operator +(const C&, const C&);
~C();
};
C obj1 ;
const C& cr = C (16)+ C (23);
C obj2 ;
Run Code Online (Sandbox Code Playgroud)
表达式C(16)+ C(23)创造了三个临时.第一个临时T1用于保存表达式C(16)的结果,第二个临时T2用于保存表达式C(23)的结果,第三个临时T3用于保存这两个表达式的相加结果.然后临时T3绑定到参考cr.未指定是先创建T1还是T2.在T2之前创建T1的实现中,保证T2在T1之前被销毁.临时值T1和T2绑定到operator +的参考参数; 这些临时值在包含对operator +的调用的完整表达式的末尾被销毁.绑定到引用cr的临时T3在cr的生命周期结束时被销毁,即在程序结束时被销毁.此外,T3被销毁的顺序考虑了具有静态存储持续时间的其他对象的销毁顺序.也就是说,因为obj1是在T3之前构造的,并且T3是在obj2之前构造的,所以保证obj2在T3之前被破坏,并且T3在obj1之前被破坏. - 末端的例子]
| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |