使用右值引用延长临时的生命周期

Jos*_*eld 9 c++ rvalue-reference move-semantics c++11

根据另一个答案,如果引用它的表达式是xvalue表达式,则右值引用不会延长临时值的生命周期.因为std::move返回一个右值引用,所以调用它的表达式是一个xvalue,所以下面的结果是一个悬空引用:

int main()
{
  std::string&& danger = std::move(get_string());  // dangling reference !
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

没关系.在std::move没有意义在这里; 它已经是一个左值.

但是这里我正在画一个空白.将xvalue表达式作为参数传递,完全标准使用std::move和rvalue引用有何不同?

void foo(const std::string& val);
// More efficient foo for temporaries:
void foo(std::string&& val);

int main()
{
  std::string s;
  foo(std::move(s)); // Give up s for efficiency
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

rvalue引用参数是否有一个特殊规则,它将延长临时的生命周期,无论它是prvalue还是xvalue?或者std::move调用表达式只是一个xvalue,因为我们传递了一个已经是rvalue的东西?我不这么认为,因为它总是返回一个右值引用,这是一个xvalue.我在这里很困惑.我想我错过了一些愚蠢的话.

Mik*_*our 8

你的第二个例子是没有传递对临时的引用,它传递对变量的引用,该引用s一直持续到结尾main().

如果是(例如foo(std::move(get_string()));),那么临时的生命周期将持续到完整表达式的结束 - 在函数返回之后.因此在内部使用它是相当安全的foo.如果foo存储一个引用/指针到它的参数,只有一个危险,而其他东西试图在以后使用它.

  • @ user1095108但是`val`不是函数`foo(std :: string && val)`体内的右值.它是"右值参考"类型的左值.获取其地址并使用其地址是完全合法的,直到`s`的生命周期结束. (4认同)

R. *_*des 7

这里没有必要延长任何生命周期:有问题的对象一直持续到结尾main,这是在结束之后foo.

  • 哦,我的上帝.我需要睡觉. (5认同)