Lun*_*oul 0 c++ operator-overloading rvalue-reference c++11
虽然在我的一些类中实现方法和运算符重载以利用C++中的右值引用,但我经常编写一些设计不良而违反DRY原则的代码.对于下面的代码片段,什么是更好的替代方案?(这段代码只是为了说明问题)
class matrix_2_2
{
int _m[2][2];
public:
matrix_2_2 operator*(const matrix_2_2& m) const &
{
matrix_2_2 res;
for(int i = 0 ; i < 2 ; i ++)
for(int j = 0 ; j < 2 ; j++)
for(int k = 0 ; k < 2 ; k++)
res._m[i][j] = (res._m[i][j] + _m[i][k]*m._m[k][j]);
return res;
}
matrix_2_2 operator*(matrix_2_2&& m) &&
{
matrix_2_2 res;
for(int i = 0 ; i < 2 ; i ++)
for(int j = 0 ; j < 2 ; j++)
for(int k = 0 ; k < 2 ; k++)
res._m[i][j] = (res._m[i][j] + _m[i][k]*m._m[k][j]);
return move(res);
}
Run Code Online (Sandbox Code Playgroud)
这段代码在实现细节中提出了很多重复,我想封装逻辑并在不同的重载中重用它,而不会失去可移动的优势,因为rvalue值左右隐含转换.
一个更好的选择是完全删除rvalue-qualified operator*并且只有一个operator*,这个:
matrix_2_2 operator*(const matrix_2_2& m) const;
Run Code Online (Sandbox Code Playgroud)
你的类是POD - 在这种情况下,移动和副本之间没有区别,因此利用移动语义来获得收益是没有可能的.您正在获得代码复杂性,但不会提高性能.如果this是&或者&&...... 你的代码应该做什么没有逻辑上的区别
这个:
matrix_2_2 operator*(matrix_2_2&& m) &&
{
matrix_2_2 res;
...
return std::move(res);
}
Run Code Online (Sandbox Code Playgroud)
这不是写这个的正确方法,因为最后一个move使得无法进行命名的返回值优化,所以你正在做一些额外move的代码,如:
matrix_2_2 product = some_matrix() * some_other_matrix();
Run Code Online (Sandbox Code Playgroud)
而不是简单地res在原地构建product.