是否可以合并具有相同逻辑但不同操作符的类的一些操作符以不复制粘贴?例如,我有一个带有操作符+=
,-=
:
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_;
};
c++有类似的东西吗:
Functor& operator(+=, -=)(const Functor& rhs) {
for (int i = 0; i < num; ++i) {
v[i][j] (+=, -=) rhs.v[i][j];
}
return *this;
}
您可以通过将lambda传递给公共实现来实现:
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_;
};
通常情况下,先实现operator+
和operator-
,再实现operator+=
和operator-=
。在这种情况下,您可以使用std::plus<double>()
和std::minus<double>()
λ如果你在c++ 14或晚(thx @StoryTeller)。
您可以通过在基类中使用操作符来进一步节省空间,将其作为从命名空间使用的操作符,或者简单地通过宏:
#define IMPLEMENT_OP(RET, OP, ARG, T)
RET operator ## OP ## (ARG rhs) {
return opImpl(rhs, T::operator ## op);
}
另一种解决这个问题的方法-仍然是通过委托-是使用constexprif
:
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_;
};