7

前段时间有人告诉我,实现二元运算符的通常模式需要move在返回中使用 final。

Matrix operator+(const Matrix &a, Matrix &&b) {
    b += a;
    return std::move(b);
}

但是现在有一个特殊规则,在return编译器中可能会将返回值视为临时值,然后就没有必要了——一个简单的return b就足够了。

但话又说回来,在这个函数中b有一个名字,因此,它是一个LValue——这会阻碍编译器将它视为临时变量,并且move是必需的。

在最新版本的 C++0x 标准中仍然是这种情况吗?我们需要move实现上述模式吗?

4

2 回答 2

7

std::move在此示例中您需要显式,因为b它不是非易失性自动对象的名称。参考12.8【class.copy】/p31/b1:

  • 在具有类返回类型的函数的 return 语句中,当表达式是具有与函数返回类型相同的 cv 非限定类型的非易失性自动对象(函数或 catch 子句参数除外)的名称时,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作
于 2011-08-21T20:04:51.110 回答
0

我不确定为什么这个函数按值返回。这个函数不应该返回Matrix&&如下内容吗?

Matrix&& operator+(const Matrix &a, Matrix &&b) {
  b += a;
  return std::move(b);
}

这具有x1 + x2 + x3 + ... + xn最多创建一个临时的额外优势,如果 Matrix 恰好是堆栈分配的,这一点很重要(因为它不会从移动中获得任何收益)。

我认为签名应该如下所示:

Matrix&& operator+(Matrix &&a,      Matrix &&b     );
Matrix&& operator+(const Matrix &a, Matrix &&b     );
Matrix&& operator+(Matrix &&a,      const Matrix &b);
Matrix   operator+(const Matrix &a, const Matrix &b);
于 2011-08-22T02:08:28.563 回答