简体   繁体   English

C ++函子用法,避免代码重复

[英]C++ functors usage, code duplication avoidance

ok so im not sure if its related to functors but from what i understood it is so the question is: lets assume i have the next class: 好的,所以我不确定它是否与函子有关,但是据我了解,问题是:假设我有下一堂课:

class Matrix{
public:
    Matrix(int, int);                       // constructor
    Matrix(const Matrix&);                  // copy constructor

    Matrix& operator+= (const Matrix&);
    Matrix& operator-= (const Matrix&);
    int* operator[] (int) const;

private:
    int rows;
    int cols;
    int** Mat_p;
};

and i want to overload the += and -= operators in Matrix class. 我想重载Matrix类中的+ =和-=运算符。
now, in order to sum or subtract 2 matrices we need to iterate over each value of both matrices and add or subtract so it will be some thing like: 现在,为了求和或减去2个矩阵,我们需要对两个矩阵的每个值进行迭代,然后加上或减去,所以将是这样的:

Matrix& Matrix::operator+= (const Matrix& M){
    for (int indexR = 0; indexR < rows; ++indexR)
        for (int indexC = 0; indexC < cols; ++indexC)
            Mat_p[indexR][indexC] += M[indexR][indexC];
}

Matrix& Matrix::operator-= (const Matrix& M){
    for (int indexR = 0; indexR < rows; ++indexR)
        for (int indexC = 0; indexC < cols; ++indexC)
            Mat_p[indexR][indexC] -= M[indexR][indexC];
}

as you can see both operators "+=" and "-=" has the same structure give or take, so one of the basic so called "rules" is to avoid code duplication. 如您所见,两个运算符“ + =”和“-=”具有相同的give或take结构,因此基本的所谓“规则”之一就是避免代码重复。
so the asked question is how do we avoid this duplication and keep the code effective ? 所以问的问题是我们如何避免这种重复并保持代码有效?

You could implement a single templated function and make two calls into it. 您可以实现一个模板函数,并对其进行两次调用。

template<typename T>
Matrix& add_or_sub (const Matrix& M, const T &op){
    for (int indexR = 0; indexR < rows; ++indexR)
        for (int indexC = 0; indexC < cols; ++indexC)
            Mat_p[indexR][indexC] = op(Mat_p[indexR][indexC], M[indexR][indexC]);
    return *this;
}

Matrix& Matrix::operator+= (const Matrix& M){
    return add_or_sub(M, std::plus());
}

Matrix& Matrix::operator-= (const Matrix& M){
    return add_or_sub(M, std::minus());
}

I'm a bit late, but I guess the example is more complete. 我有点迟了,但是我想这个例子比较完整。 I would suggest writing a piecewise functor applicator which uses underlying scalar as operands, and returns the same type as well, and implement operators using this. 我建议编写一个分段函子应用程序,该应用程序使用基础标量作为操作数,并返回相同的类型,并使用此实现操作符。

An example: 一个例子:

#include <iostream>
#include <functional>
using namespace std;

template <int Rows, int Cols, typename Scalar = int>
class Matrix {
    public:
    void piecewise_apply(const Matrix& other, std::function<Scalar(Scalar,Scalar)> f) {
        for (int indexR = 0; indexR < Rows; ++indexR)
            for (int indexC = 0; indexC < Cols; ++indexC)
                data[indexR][indexC] = f(data[indexR][indexC], other.data[indexR][indexC]);
    }

    Matrix<Rows,Cols,Scalar>& operator+=(const Matrix<Rows,Cols,Scalar>& rhs) {
        piecewise_apply(rhs, std::plus<Scalar>());
        return *this;
    }

    Matrix<Rows,Cols,Scalar>& operator-=(const Matrix<Rows,Cols,Scalar>& rhs) {
        piecewise_apply(rhs, std::minus<Scalar>());
        return *this;
    }
    private:
    Scalar data[Rows][Cols];
};

int main() {
    Matrix<5,5> a;
    Matrix<5,5> b;

    a.piecewise_apply(b, [](int a, int b){return a*b;});
    a -= b;
    return 0;
}

The example is not complete, as it lacks initialization. 该示例不完整,因为它缺少初始化。 Also there is no protection when &rhs == this (a interesting place for optimizations), and probably some more, but it shows the idea. &rhs == this (优化的一个有趣的地方)时,也可能没有更多的保护,但是它表明了这个主意。 As for code efficiency.. well you should rely on the compiler on this one. 至于代码效率,那么您应该在这一方面依靠编译器。

One advantage of this approach is that, even if it's a bit slower in the default version, you can try writing piecewise_apply which uses more elaborate optimization techniques, like blocking, or parallelization, etc. and get speedups in various places. 这种方法的一个优点是,即使默认版本的速度稍慢,您也可以尝试编写piecewise_apply ,它使用更复杂的优化技术(例如阻塞或并行化等),并在各个地方实现加速。

For a simple version, like in your example, the copy-paste version is shorter, and easier to understand, so probably a better choice. 对于简单的版本(例如您的示例),复制粘贴版本较短,并且易于理解,因此可能是更好的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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