Home > Blockchain >  How to merge different operators with the same logic in C class for not copypasting
How to merge different operators with the same logic in C class for not copypasting

Time:07-01

Is it possible to merge some operators of class that have same logic but different operators to not copypasting. For example, I have class with operators =, -=:

class Matrix {
public:
    Functor& operator =(const Functor& rhs) {
        for (int i = 0; i < num;   i) {
            v[i][j]  = rhs.v[i][j];
        }
        return *this;
    }

    Functor& operator-=(const Functor& rhs) {
        for (int i = 0; i < num;   i) {
            v[i][j] -= rhs.v[i][j];
        }
        return *this;
    }

private:
    int rows_ {};
    int columns_ {};
    std::vector<std::vector<double>> matrix_;
};

Does C has something like:

Functor& operator( =, -=)(const Functor& rhs) {
        for (int i = 0; i < num;   i) {
            v[i][j] ( =, -=) rhs.v[i][j];
        }
        return *this;
    }

CodePudding user response:

You can do it by passing a lambda to a common implementation:

class Matrix {
private:
    template<typename Op>
    Functor& opImpl(const Functor& rhs, Op op) {
        for (int i = 0; i < num;   i) {
            Op(v[i][j], rhs.v[i][j]);
        }
        return *this;
    }

public:
    Functor& operator =(const Functor& rhs) {
        return opImpl(rhs, [&](double& l, const double r) { r  = l; });
    }

    Functor& operator-=(const Functor& rhs) {
        return opImpl(rhs, [&](double& l, const double r) { r -= l; });
    }

private:
    int rows_ {};
    int columns_ {};
    std::vector<std::vector<double>> matrix_;
};

Normally, you'd first implement operator and operator- and implement operator = and operator-= in terms of the former. In that case, you can use std::plus<double>() and std::minus<double>() for the lambda if you're in c 14 or later (thx @StoryTeller).

You can further save space by either having the operators in a base class, having it as using from a namespace or simply by a macro:

#define IMPLEMENT_OP(RET, OP, ARG, T) \
   RET operator ## OP ## (ARG rhs) { \
      return opImpl(rhs, T::operator ## op); \
   }
  • Related