考虑以下.
#include <string>
using std::string;
string middle_name () {
return "Jaan";
}
int main ()
{
string&& danger = middle_name(); // ?!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这不会计算任何东西,但它编译时没有错误,并演示了一些让我感到困惑的事情:danger
是一个悬空引用,不是吗?
sel*_*tze 42
右值引用是否允许悬空引用?
如果你的意思是"是否有可能创建悬空右值参考",那么答案是肯定的.然而,你的例子,
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;
}
Run Code Online (Sandbox Code Playgroud)
很好.同样的规则适用于此示例(Herb Sutter的文章)也是安全的.如果使用纯 rvalue初始化引用,则临时对象的生命周期将延长到引用的生命周期.不过,你仍然可以制作悬空参考.例如,这不再安全:
int main()
{
string&& danger = std::move(middle_name()); // dangling reference !
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于std::move
回报string&&
(这是不是一个纯粹的右值),它扩展了临时的生活时不适用该规则.在这里,std::move
返回一个所谓的xvalue.一个x值只是一个不知名的右值引用.因此它可以引用任何东西,并且基本上不可能在不查看函数的实现的情况下猜测返回的引用所引用的内容.
fre*_*low 15
右值引用绑定到右值.右值是prvalue或xvalue [ 说明 ].绑定到前者永远不会创建悬挂引用,绑定到后者可能.这就是为什么选择T&&
函数的返回类型通常是个坏主意.std::move
是这个规则的一个例外.
T& lvalue();
T prvalue();
T&& xvalue();
T&& does_not_compile = lvalue();
T&& well_behaved = prvalue();
T&& problematic = xvalue();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3064 次 |
最近记录: |