2016-12-06 7 views
2

확인 그래서 메신저 확실하지 회피 내가 그렇게 입니다 이해 무엇 펑뿐만로부터 관련 질문은 :C++ 펑 사용, 코드 중복의 경우

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

과 : 내가 다음 클래스가 있다고 가정 할 수 있습니다 Matrix 클래스에서 + = 및 - = 연산자를 오버로드하려고합니다.

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

당신이 두 사업자 "를 볼 수 + =
지금,이 행렬 합계 또는 빼기 위해 우리는 어떤 일이 같은이 될 것입니다 두 행렬의 각 값을 반복하고 추가 정도 뺄 필요 "및"- = "은 동일한 구조 또는 줄기를 가지므로 기본"소위 "규칙 중 하나는 코드 중복을 피하는 것입니다.
질문은 우리가 어떻게이 중복을 피하고 코드를 효과적으로 유지할 수 있는지입니다.

+0

이 작은 양의 코드 복제는 실제 문제가 아닙니다. – Brian

+0

@ 브라이언 글쎄, 그래도 나는 그것을 피하고 싶습니다. (어떤 식 으로든 그냥 예를 들어 ...) –

답변

4

하나의 템플릿 함수를 구현하고 두 개의 호출을 호출 할 수 있습니다.

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()); 
} 
+2

4 분 늦었습니다. 그래도. 나는 이것이'add_or_sub'' piecewise_apply'의 이름을 짓는 것이 낫다고 생각합니다. 멤버 함수로 쓰이는 경우'M' 또는'* this'를 반환하지 않아야합니까? – luk32

+0

@ luk32 방금 질문에서 코드를 복사했는데'return'이 누락되었다는 것을 눈치 채지 못했습니다. 추신 [명명은 어렵다] (http://martinfowler.com/bliki/TwoHardThings.html). –

+0

@ MarkRansom 고마워, 많은 감사, 내가 다른 연산자 과부하를 추가 할 수 있다고 말하자면, 스칼라 매개 변수 (int)를 사용하여 * = 또는 * (할당없이) 말할 수 있습니다. 즉, 행렬의 각 노드에 스칼라 int . 지정된 템플릿으로 주어진 코드에서 구현 될 수 있습니까 ?? 미리 감사드립니다. –

2

조금 늦었습니다. 그러나 예제가 더 완벽하다고 생각합니다. 필자는 기본 스칼라를 피연산자로 사용하는 piecewise functor applicator를 작성하고 동일한 유형을 반환하고 이것을 사용하여 연산자를 구현하는 것이 좋습니다.

예 :이 초기화 부족으로

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

예는, 완료되지 않았습니다. 또한 &rhs == this (최적화를위한 흥미로운 장소), 그리고 아마 더 많은 것은 보호가 없지만 아이디어를 보여줍니다. 코드 효율성에 관해서는 ..이 컴파일러에 의존해야합니다.

기본 버전에서 조금 느린 경우에도 블로킹이나 병렬 처리 등과 같은보다 정교한 최적화 기술을 사용하여 다양한 장소에서 속도를 높일 수있는 piecewise_apply을 작성할 수 있습니다.

예에서와 같이 단순한 버전의 경우 복사 붙여 넣기 버전이 짧고 이해하기 쉽기 때문에 더 나은 선택 일 수 있습니다.

+0

좋은 답변입니다. 감사합니다. –