Cri*_*iss 7 c++ reference temporary lifetime language-lawyer
关于从函数返回并绑定到rvalue/const左值引用的对象的生命周期的延长,我有一些不清楚的信息.来自这里的信息.
不会扩展对return语句中函数的返回值的临时绑定:它会在返回表达式的末尾立即销毁.这样的函数总是返回一个悬空引用.
如果我理解正确,引用声称返回语句返回的对象的生命周期是不可扩展的.但最后一句话表明,它只适用于返回引用的函数.
在海湾合作委员会,从下面的代码我得到以下输出:
struct Test
{
Test() { std::cout << "creation\n"; }
~Test() { std::cout << "destruction\n"; }
};
Test f()
{
return Test{};
}
int main()
{
std::cout << "before f call\n";
Test && t = f();
std::cout << "after f call\n";
}
Run Code Online (Sandbox Code Playgroud)
before f call
creation
after f call
destruction
Run Code Online (Sandbox Code Playgroud)
所以看起来生命延长了.
是否应延长与此类参考相关的临时对象的生命周期?您还可以提供更明确的信息来源吗?
所以看起来生命延长了.
该代码是相当有效的,但要注意,它的寿命延长得到了是不是在函数内部创建的临时对象的对象f()的Test{},它是由该函数返回的对象f().返回的对象是从临时对象移动构造的,然后被绑定到t,生命周期被扩展.BTW返回的对象是按值返回的,它也是临时的.
要观察,您可以手动添加移动构造函数:
struct Test
{
Test() { std::cout << "creation\n"; }
~Test() { std::cout << "destruction\n"; }
Test(Test&&) { std::cout << "move\n"; }
};
Run Code Online (Sandbox Code Playgroud)
并使用禁止复制省略模式编译和运行,结果是:
before f call
creation // the temporary created inside f
move // return object move-constructed
destruction // the temporary destroyed
after f call
destruction // the returned object destroyed
Run Code Online (Sandbox Code Playgroud)
标准引用,§15.2/ 6临时对象[class.temporary]:
绑定引用的临时对象或绑定引用的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:
(6.1)绑定到函数调用中的引用参数的临时对象将持续存在,直到包含该调用的完整表达式完成.
(6.2)函数返回语句中返回值的临时绑定的生存期不会延长; 临时在return语句中的full-expression结束时被销毁.
(6.3)new-initializer中对引用的临时绑定一直持续到包含new-initializer的full-expression完成为止.[例如:
Run Code Online (Sandbox Code Playgroud)struct S { int mi; const std::pair<int,int>& mp; }; S a { 1, {2,3} }; S* p = new S{ 1, {2,3} }; // Creates dangling reference- 结束示例] [注意:这可能会引入悬空引用,并鼓励实现在这种情况下发出警告. - 结束说明]