返回本地对象右值引用,正确或错误
Return a local object rvalue reference,right or wrong?
我看到一旦返回一个本地对象,编译器就会进行返回值优化。RVO,NRVO)。
标准祝福RVO的部分继续说,如果 满足 RVO 的条件,但编译器选择不执行 复制 elision,必须将返回的对象视为右值。
所以我们只是写这样的代码:
Widget makeWidget()
{
Widget w;
…
return w;//never use std::move(w);
}
我从未见过有人写这样的代码:
Widget&& makeWidget()
{
Widget w;
…
return std::move(w);
}
我知道返回本地对象的左值引用总是错误的。那么,返回本地对象的右值引用也是错误的吗?
返回对局部自动变量的引用总是错误的。当函数返回时,变量将被销毁,因此对引用的任何使用都会给出未定义的行为。
无论是右值还是左值引用都没有区别。
当函数返回时,本地对象已被释放。
如果编写这样的代码:
Widget&& makeWidget()
{
Widget w;
…
return std::move(w);
}
因此,请考虑以下三段代码:
第一:
Widget&& w= makeWidget();//w is a dangling reference,variable will be destroyed when the function returns
第二:
void foo(Widget&& w){...}//w is a dangling reference too
foo(makeWidget());
第三:
void foo(Widget w){...}//OK,will copy it
foo(makeWidget());
所以答案是错误的。
请注意:
右值引用可用于延长可修改临时的生存期(请注意,对 const 的右值引用也可以延长生存期,但它们不可修改)
每当引用绑定到临时对象或基子对象时 临时的,临时的寿命延长以匹配 引用的生存期,但以下情况除外:
在 return 语句中,临时绑定到函数的返回值不会扩展:它在 返回表达式。此类函数始终返回悬空引用。
函数调用中引用参数的临时绑定一直存在,直到包含该参数的完整表达式结束 函数调用:如果函数返回引用,则引用的寿命超过生存期 完整的表达,它变成了一个悬而未决的参考。
与 new-表达式中使用的初始值设定项中的引用的临时绑定一直存在,直到包含以下内容的完整表达式结束 那个新表达式,不如初始化的对象那么长。如果初始化的对象比完整表达式的寿命长,则其引用成员 成为悬而未决的参考。
Widget&& makeWidget(){
return Widget(123);//error
}
是的,这是错误的。 不会发生引用生存期延长,因此引用引用已销毁的值,并且使用它(几乎)1 都是未定义的行为。 不应返回悬空引用或指针。
1:decltype
不是真正的使用,但它也不是UB。 所以就是这样。 存储对它的引用也不是 UB。 也不是真的用。
不幸的是,Widget w;
在堆栈上,当您将引用传递给另一个函数时,w
将被销毁...按值传递对象将避免对象被销毁。
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- C++引用错误
- 已定义函数时出现 G++ "未定义的引用"错误
- 错误:使用通用引用的声明冲突
- 链接 cmake 时出现未定义的引用错误
- 错误:未定义对'oboe::AudioStreamBuilder::openStream(oboe::AudioStream**)'的引用
- 链接器错误:未定义对"Reference_Genome::seq[abi:cxx11]"的引用
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 错误:无法解析对重载函数的引用;你的意思是调用它吗?
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- 运行时错误:引用绑定到类型为"int"的空指针
- 隐式重新解释引用时强制转换,没有警告/错误
- 只有级联分类器会发出未定义的引用错误
- 错误:未定义对cv::cudacodec::createVideoReader的引用
- 模板流运算符重载错误:引用初始化无效,与basic_istream和basic_ifstream之间的差异有关
- 对于我的 ComplexNumber 中的某些方法,我得到了一个奇怪的未定义错误引用.cpp,不过我对模板很陌生
- 从对象调用成员对象,错误:引用非常量值的初始值必须是左值
- Qt并发错误:引用非静态成员