7

如果我没记错的话,我认为 const 引用和 rvalue 引用都可以绑定到 rvalue。返回前者的函数和返回后者的函数之间有什么实际区别吗?

编辑。我不能修改前者,但为什么我会对修改右值感兴趣?是否有意义?

4

2 回答 2

16

左值const引用可以绑定到任何东西。右值引用只能绑定到非右值const

            non-const lvalue   const lvalue   non-const rvalue   const rvalue
const T&    yes                yes            yes                yes
T&&         no                 no             yes                no

如您所见,它们非常不同。

此外,如果函数调用返回左值引用,则该表达式是左值,但如果函数调用返回对对象的右值引用,则该表达式是 xvalue。

如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值,如果结果类型是对对象类型的右值引用,则为 xvalue,否则为纯右值。

至于你什么时候想要修改一个右值——这正是移动语义的全部意义所在。考虑以下函数调用:

void func(std::string);

func(std::string("Hello"));

该表达式std::string("Hello")是一个创建临时对象的右值。使用此右值初始化std::string参数时,它将选择采用右值引用的构造函数 -移动构造函数。然后,此构造函数从右值中窃取内容,这通常比进行完整复制要快得多。我们可以从中窃取,因为我们知道它是暂时的。

至于何时应该返回const左值引用或右值引用:

  • const当您想要授予读取“内部”对象(可能是类的成员)但不允许人们修改它的访问权限时,最常使用返回左值引用。

  • 当您希望允许调用代码从“内部”对象(可能是类的成员)移动时,最常用(根本不常见)返回右值引用。因此,它们不是从临时返回的对象移动(就像按值返回时那样),而是从内部对象移动。

    这也可以通过非const左值引用来实现,但是他们必须明确地指出std::move它。

因此,您不太可能需要返回右值引用。

并不是那种std::forward返回类型看起来像T&&. 但是,这是具有欺骗性的,因为它可能是也可能不是右值引用,具体取决于T. 请参阅通用参考

于 2013-03-28T12:23:44.270 回答
4

返回前者的函数和返回后者的函数之间有什么实际区别吗?

这个问题似乎不正确。返回常量左值引用的函数提供对对象的访问仅用于读取,而返回右值引用的函数提供对移动的访问,这意味着调用者可以获取引用对象的内容并将其移动到不同的目的。它们在任何方面都没有可比性。

在这两种情况下,引用必须指向一个对象,其生命周期超出返回它的函数的末尾,否则调用者将在使用该引用时出现未定义的行为。

于 2013-03-28T13:05:17.070 回答