Issue
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;
}
Solution
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 < rows_; ++i) {
for (int j = 0; j < columns_; ++j) {
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); \
}
Another way to solve this - still by delegating - is to use constexpr if
:
class Matrix {
private:
template<char op1, char op2 = ' '>
Functor& opImpl(const Functor& rhs) {
for (int i = 0; i < rows_; ++i) {
for (int j = 0; j < columns_; ++j) {
if constexpr (op1 == '+' && op2 == '=') {
v[i][j] += rhs.v[i][j];
}
if constexpr (op1 == '-' && op2 == '-') {
v[i][j] -= rhs.v[i][j];
}
// TODO: further ops, error handling here
}
}
return *this;
}
public:
Functor& operator+=(const Functor& rhs) {
return opImpl<'+', '='>(rhs);
}
Functor& operator-=(const Functor& rhs) {
return opImpl<'-', '='>(rhs);
}
private:
int rows_ {};
int columns_ {};
std::vector<std::vector<double>> matrix_;
};
Answered By - lorro Answer Checked By - Candace Johnson (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.