返回const引用和rvalue引用之间的区别

jbg*_*bgs 7 c++ rvalue-reference c++11

如果我没错,我认为const引用和rvalue引用都可以绑定到rvalue.返回前者的函数和返回后者的函数之间是否存在实际差异?

编辑.我无法修改前者,但为什么我有兴趣修改右值?是否有意义?

Jos*_*eld 16

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

            non-const lvalue   const lvalue   non-const rvalue   const rvalue
const T&    yes                yes            yes                yes
T&&         no                 no             yes                no
Run Code Online (Sandbox Code Playgroud)

如你所见,它们非常不同.

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

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

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

void func(std::string);

func(std::string("Hello"));
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 当你想允许调用代码从"内部"对象(可能是类的成员)移动时,返回rvalue引用是最常用的(根本不常见).因此,它们不是从临时返回的对象移动(就像通过值返回时那样),而是从内部对象移动.

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

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

不是那样std::forward的返回类型T&&.但是,这具有欺骗性,因为它可能是也可能不是右值引用,具体取决于类型T.见通用参考文献.