当您使用 std::move 返回时,"return-by-rvalue-ref" 和 "return-by-value" 之间的区别?

Difference between "return-by-rvalue-ref" & "return-by-value" when you return using std::move?

本文关键字:return-by-value return-by-rvalue-ref 之间 区别 std move 返回      更新时间:2023-10-16

考虑以下代码:

#include <iostream>
using namespace std;
struct I {
    I(I&& rv) { cout << "I::mvcotr" << endl; }
};
struct C {
    I i;
    I&& foo() { return move(i) };
    }
};
int main() {
    C c;
    I i = c.foo();
}

C包含I,而C::foo()允许您将I移出C。

I&& foo() { return move(i) }; // return rvalue ref

和以下替代成员函数:

I foo() { return move(i) }; // return by value

对我来说,它们似乎做同样的事情:I i = c.foo();导致对I::I(I&&);的调用。

本例中没有涉及的后果是什么?

不考虑您编写的程序是否真正有意义(从数据成员移动是尴尬的-但是好吧,也许有一些用例),在这种情况下,该函数的两个版本最终做同样的事情。

作为一般实践,您应该更喜欢按值返回,因为在许多情况下,它允许编译器执行复制省略并省略对返回类型的move构造函数的调用,正如c++ 11标准第12.8/31段所允许的那样。

复制省略允许编译器直接在对象中创建函数的返回值,该对象应该从函数的返回值初始化。

因此,作为一般准则,更倾向于按值返回