2016-10-24 33 views
5

Odkrywam C++ i chciałbym stworzyć mini matematyczną bibliotekę Matrix przy użyciu szablonów.Szablon przeciążenia operatora C++ z różnymi argumentami

Tutaj chcę przeciążać operatora *.

Jeśli mogę opisać matrycę tak: M(y, x) z M nazwa macierzy y i x wysokość i szerokość, mnożenie macierzy powinien wyglądać tak:

M(a, b) * N(b, c) = R(a, c) 

Obecnie mam ten kod:

template<unsigned int y, unsigned int x> 
class Matrix 
{ 
public: 
    Matrix() { } 
    ~Matrix() { } 

    Matrix<y, x2>& operator*(const Matrix<y2, x2>& right) 
    { 
     // code... 
    } 
private: 
    std::array<std::array<double, x>, y> m_values; 
}; 

Więc chciałbym, aby móc się rozmnażać dwa differents matryca tak:

Matrix<3, 4> m; 
Matrix<4, 2> n; 

// fill the matrix with values 

Matrix<3, 2> o = m * n; 

Szukałem, ale nie znalazłem odpowiedzi na to pytanie (może dlatego, że tak naprawdę nie wiem, co muszę dokładnie przeszukać).

Dzięki za pomoc :)

Odpowiedz

3

Musisz zrobić swój operator*szablon funkcji członka, coś tak:

template <unsigned int y2, unsigned int x2> 
Matrix<y, x2> operator*(const Matrix<y2, x2>& right) 
{ 
    // code... 
} 

Zauważ, że zwracany typ nie jest już punktem odniesienia, jako operator* powinien zwrócić nową wartość - jeśli chcesz, możesz zdefiniować komplementarną operator*=, która modyfikuje macierz LHS na miejscu.

Inną rzeczą, którą należy zauważyć, jest to, że mnożenie macierzy ma sens tylko wtedy, gdy wymiary macierzy są zgodne: to znaczy, jeśli liczba kolumn w LHS odpowiada liczbie wierszy w RHS. Aby to wymusić, można użyć static_assert wewnątrz swojej funkcji składowej, aby upewnić się, że parametry szablonu są zgodni:

template <unsigned int y2, unsigned int x2> 
Matrix<y, x2> operator*(const Matrix<y2, x2>& right) 
{ 
    static_assert(y2 == x, "Matrix dimensions mismatched"); 
    // code... 
} 
0

Jest to dość proste, określenie operator* jako szablon funkcji. Przykładowy szablon funkcji:

template<unsigned y1, unsigned x1, unsigned y2, unsigned x2> 
Matrix<y1, x2> operator*(Matrix<y1, x1> const& l, Matrix<y2, x2> const& r) 
{ 
    // static_assert(x1 == y2, "Matrices cannot be multiplied"); 
    Matrix<y1, x2> ret{}; 
    // multiply 
    return ret; 
} 

Należy pamiętać, że operator* zwraca wartość. jest to szczególnie ważne, ponieważ zwracasz inny typ i nie masz żadnego obiektu, który zwróci odniesienie do (poprawności idiomatycznej na bok).