考虑一下下面的内容。
#include <string>
using std::string;
string middle_name () {
return "Jaan";
}
int main ()
{
string&& danger = middle_name(); // ?!
return 0;
}这不计算任何东西,但它编译时没有错误,并且演示了一些我感到困惑的东西:danger是一个悬空引用,不是吗?
发布于 2010-09-15 17:32:52
右值引用允许悬空引用吗?
如果你的意思是“是否可以创建悬空的右值引用”,那么答案是肯定的。然而,你的例子,
string middle_name () {
return "Jaan";
}
int main()
{
string&& nodanger = middle_name(); // OK.
// The life-time of the temporary is extended
// to the life-time of the reference.
return 0;
}完全没问题。同样的规则也适用于这里,这使得this example ( Herb Sutter的文章)也是安全的。如果使用纯r值初始化引用,则临时对象的生存期将扩展到引用的生存期。不过,您仍然可以生成悬空引用。例如,这不再安全:
int main()
{
string&& danger = std::move(middle_name()); // dangling reference !
return 0;
}因为std::move返回一个string&& (它不是纯 rvalue),所以延长临时值的生命周期的规则不适用。在这里,std::move返回一个所谓的x值。xvalue只是一个未命名的rvalue引用。因此,它可以引用任何东西,如果不查看函数的实现,基本上不可能猜测返回的引用是指什么。
发布于 2010-09-15 18:23:01
右值引用绑定到右值。右值可以是pr值,也可以是x值[explanation]。绑定到前者永远不会创建悬空引用,绑定到后者可能会。这就是为什么选择T&&作为函数的返回类型通常不是一个好主意。std::move是此规则的一个例外。
T& lvalue();
T prvalue();
T&& xvalue();
T&& does_not_compile = lvalue();
T&& well_behaved = prvalue();
T&& problematic = xvalue();发布于 2010-09-15 17:29:00
danger是一个悬而未决的引用,不是吗?
如果您使用了const &,则不会更多:danger将获得rvalue的所有权。
https://stackoverflow.com/questions/3716277
复制相似问题