C++:对右值的常量引用
c++: const reference to an rvalue
//old school '98 c++, no C++0x stuff
std::string getPath();
void doSomething()
{
const std::string &path = getPath(); //const reference to an rvalue
... // doSomething with path
}
void doSomething2()
{
const std::string path = getPath(); //regular variable
... // doSomething with path
}
doSomething和doSomething2之间有什么区别,哪一个是可取的?
在 doSomething 中使用对返回的 rvalue 的 const 引用是否安全?
doSomething2 是否创建了返回的 rvalue 的副本,编译器是否可以在此处进行 rvalue 优化?
在 doSomething 中使用对返回的 rvalue 的 const 引用是否安全?
是的,这完全没问题。该语言有一个特定的子句,该子句保证如果将引用绑定到右值,则会创建一个临时的,并且生存期将延长到创建引用的范围结束。
doSomething2 是否创建了返回的 rvalue 的副本,编译器是否可以在此处进行 rvalue 优化?
在这两种情况下,成本是相同的,因为编译器将执行RVO(返回值优化(
doSomething和doSomething2之间有什么区别,哪一个是可取的?
主要区别在于,在一种情况下,您为真实对象命名,而在另一种情况下,名称被赋予引用。编译器应在两个版本中生成完全相同的代码。
话虽如此,我发现使用const&
具有误导性。它给人的印象是本地函数在某处引用了某个对象,但它实际上有一个副本(没有名称(。要意识到这是一个副本,维护者必须查看并验证正在调用的函数的签名。在值的情况下,行为更明显:函数维护函数返回的任何内容的副本(可能是值或引用(。
第二个区别是,法律上只允许您绑定 const 引用,这意味着该函数不能修改对象。在存储值的情况下,类型可以是非常量,函数可以修改该对象,因此该方法更灵活。
在 C++03 中,使用 const& trick 的唯一原因是,你知道函数返回一个值,你知道该类型派生自一个众所周知的基,并且你不想命名该类型 [看看 ScopeGuard]。在 C++11 中,这种使用不再重要,因为您只需使用 auto
让编译器自动找出类型即可。
(从其他评论来看,当您将引用绑定到有关其寿命的右值时,这似乎C++标准版本取决于保证人 - 这个答案反映了C++经典(
做某事有参考什么?
doSomething2 有一个可能不再存在的东西的副本,这很好
让我们看看getPath((:
通常,它将获取返回值,将其复制到堆栈,然后将其复制到LHS它可以直接分配给 LHS
它可以返回"hello",这将在堆栈上创建一个字符串 - 这不能被引用,因为它是临时的(doSomething的问题(
它可以返回一个静态的 const 字符串 - 在这种情况下,它可以完全内联并分配给 LHS
std::string
在函数getPath()
内分配并在从该函数返回时销毁,则引用版本可能具有悬空引用。然后,这是危险的用法。
如果你有一个保存该字符串的类,并且该类的寿命超过了该const std::string &
引用的范围MyClass::getPath()
,那么在这种情况下,引用就不会悬而未决。
第二个版本将始终有效。
- 什么时候在C++中返回常量引用是个好主意
- 通过常量引用传递参数的矩阵模板类
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么常量方法可以采用非常量引用?
- 为什么当我们有常量引用时创建临时对象?
- 如何返回向量的常量引用?
- C++:常量引用参数
- 不同于按值传递和常量引用传递的程序集
- 为什么const_cast和static_cast常量引用没有效果?
- C++ 获取函数在常量引用中按值返回的结果
- 从 BubbleSort* 类型的右值初始化 'AssortedSorter&' 类型的非常量引用无效"
- C++ 在类中使用常量引用文本时 O2 内存泄漏
- 是否可以跨 dll 边界返回常量引用/指向 std::vectors?
- C++中大多数/所有 setter 函数的参数是否应该写为常量引用?
- 通过非常量引用参数修改常量引用参数
- 将常量引用传递给线程
- 为什么C++中没有常量引用,就像常量指针一样?