前段时间我被告知,实现两元运算符的通常模式在返回时需要最终move
。
Matrix operator+(const Matrix &a, Matrix &&b) {
b += a;
return std::move(b);
}
但是现在有一个特殊的规则,在return
编译器可能会将返回值视为临时值,然后这不是必需的 - 简单的return b
就足够了。
但是再次,b
在此函数中有一个名称,因此,它的 LValue - 这阻碍了编译器认为它是一个temp,move
是必需的。
在最新版本的C ++ 0x Standard中,情况仍然如此吗? 我们需要move
来实现上述模式吗?
答案 0 :(得分:7)
在此示例中,您需要明确的std::move
,因为b
不是非易失性自动对象的名称。参考12.8 [class.copy] / p31 / b1:
- 在具有类返回类型的函数的return语句中,何时 表达式是非易失性自动对象的名称(其他 比函数或catch子句参数)具有相同的cv- 非限定类型作为函数返回类型,复制/移动操作 可以通过直接构造自动对象来省略 函数的返回值
答案 1 :(得分: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);