如果我没错,我认为const引用和rvalue引用都可以绑定到rvalue。返回前者的函数和返回后者的函数之间是否存在实际差异?
EDIT。我不能修改前者,但为什么我有兴趣修改右值?它有意义吗?
答案 0 :(得分: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,否则为prvalue。
至于你何时想要修改一个右值 - 这正是移动语义的全部意义所在。请考虑以下函数调用:
void func(std::string);
func(std::string("Hello"));
表达式std::string("Hello")
是一个创建临时对象的右值。使用此rvalue初始化std::string
参数时,它将选择采用右值引用的构造函数 - 移动构造函数。然后,这个构造函数从rvalue中窃取东西,这通常比执行完整拷贝要快得多。我们可以从中窃取,因为我们知道它是暂时的。
至于何时应返回const
左值引用或右值引用:
当您想要授予读取“内部”对象(可能是类的成员)的访问权限但不允许人们修改它时,最常使用返回const
左值引用。 / p>
当您希望允许调用代码从“内部”对象(可能是类的成员)移动时,返回最常用的rvalue引用(根本不常见)。因此,它们不是从临时返回的对象移动(就像通过值返回时那样),而是从内部对象移动。
使用非const
左值参考也可以实现这一点,但是他们必须明确std::move
它。
因此,您不太可能需要返回右值参考。
不是std::forward
的返回类型看起来像T&&
。但是,这具有欺骗性,因为根据T
的类型,它可能是也可能不是右值引用。请参阅universal references。
答案 1 :(得分:2)
返回前者的函数和返回后者的函数之间是否存在实际差异?
问题似乎是不正确的。返回常量 lvalue-reference 的函数仅提供对读取的对象的访问权限,而返回 rvalue-reference 的函数提供访问权限对于移动,这意味着调用者可以获取被引用对象的内容,并将移动到另一个对象。它们无论如何都无法比较。
在这两种情况下,引用必须指向一个对象,其生命周期超出返回它的函数的末尾,否则调用者将在使用该引用时以未定义的行为跳转。