简体   繁体   中英

how to implement movable overloads without violating the DRY principle in C++?

While implementing method and operator overloading in some of my classes to leverage the rvalue references in C++, often I write some code with poor design violating the DRY Principle. What would be a better alternative for the code snippet below? (This code is just to illustrate the problem)

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);
    }

This code presents a lot of repetition in the implementations details, I would like to encapsulate the logic and reuse it in different overloads, without losing the movable advantage because of rvalue to lvalue implicity conversions.

A better alternative would be to just delete the rvalue-qualified operator* completely and have just the one operator* , this one:

    matrix_2_2 operator*(const matrix_2_2& m) const;

Your class is a POD - there is no difference between a move and a copy in this case, so there is no possible advantage for you to gain by taking advantage of move semantics. You're gaining in code complexity, but not in performance. There really is no logical difference for what your code should do if this is & or && ...

Also, this:

matrix_2_2 operator*(matrix_2_2&& m) &&
{
    matrix_2_2 res;
    ...
    return std::move(res);
}

is not the correct way to write that, as the last move makes it impossible to do the named return value optimization, so you're doing an extra move for code like:

matrix_2_2 product = some_matrix() * some_other_matrix();

Rather than simply constructing res in-place in product .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM