【发布时间】:2013-11-20 18:21:45
【问题描述】:
下面的代码说明了我的担忧:
#include <iostream>
struct O
{
~O()
{
std::cout << "~O()\n";
}
};
struct wrapper
{
O const& val;
~wrapper()
{
std::cout << "~wrapper()\n";
}
};
struct wrapperEx // with explicit ctor
{
O const& val;
explicit wrapperEx(O const& val)
: val(val)
{}
~wrapperEx()
{
std::cout << "~wrapperEx()\n";
}
};
template<class T>
T&& f(T&& t)
{
return std::forward<T>(t);
}
int main()
{
std::cout << "case 1-----------\n";
{
auto&& a = wrapper{O()};
std::cout << "end-scope\n";
}
std::cout << "case 2-----------\n";
{
auto a = wrapper{O()};
std::cout << "end-scope\n";
}
std::cout << "case 3-----------\n";
{
auto&& a = wrapper{f(O())};
std::cout << "end-scope\n";
}
std::cout << "case Ex-----------\n";
{
auto&& a = wrapperEx{O()};
std::cout << "end-scope\n";
}
return 0;
}
现场观看here。
据说auto&&会延长临时对象的生命周期,但是我找不到这条规则的标准词,至少在N3690中找不到。
最相关的可能是关于临时对象的第 12.2.5 节,但不完全是我想要的。
那么,auto&& 生命周期延长规则是否适用于所有表达式中涉及的临时对象,还是仅适用于最终结果?
更具体地说,a.val 在我们到达案例 1 的范围结束之前是否保证有效(非悬空)?
编辑: 我更新了示例以显示更多案例(3 和 Ex)。
您会看到,只有在情况 1 中,O 的生命周期才会延长。
【问题讨论】:
-
与
auto&& val = wrapper{O()}.val,没有。 -
@Jamboree 您是专门询问
auto&&还是只是延长寿命? (推导出auto&&后,引用绑定的默认规则适用。要么是wrapper const&,要么是wrapper&&,否则绑定将失败。) -
@Jamboree IMO N3690 目前是一个奇怪的文档。它包含一些 C++1y 特性,但 N3979 是最新的公开草案(除了 github repository)。
-
见open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#1697。 EDG 和 GCC 不会延长使用寿命。我对意图的理解到目前为止不会被扩展(我认为实现的行为“正确”而不是标准中的描述)。我们需要看看这个问题将如何解决,以及官方的实现是否会出错。
-
特别是看 12.2p5 中的最后一个项目符号示例,它还初始化了一个引用成员,根据示例的注释,您可以在其中看到生命周期延长
标签: c++ c++11 auto temporary lifetime