2016-03-07 41 views
0
template<typename T> 
class Matrix 
{ 

    template<typename U> 
    friend 
    Matrix<U> operator+(const Matrix<U>& a, const Matrix<U>& b); 


protected: 

    size_t _m, _n; 
    T *_alloc; 
}; 

template<typename U> 
Matrix<U> operator+(const Matrix<U>& a, const Matrix<U>& b) 
{ 
    if(a._m == b._m && a._n == b._n) 
    { 
     Matrix<U> ret(a._m, a._n); 

     // ... 

     return ret; 
    } 
    else 
    { 
     throw "Matrix dimension mismatch error"; 
    } 
} 

我在使用非模板類之前沒有問題地重載了operator+。這裏我使用了一個模板類。C++在模板類中重載operator +

Matrix<U> Matrix<U>::operator+(const Matrix<U>&, const Matrix<U>&)必須採用零或一個參數。

似乎編譯器忽略了friend關鍵字。

我也試過

friend 
template<typename U> 
Matrix<U> operator+(const Matrix<U>& a, const Matrix<U>& b); 

但是,這給了我一個不同的編譯器錯誤。

expected unqualified-id before 'template'

我如何能超載operator+與模板類?

+0

相關:http://stackoverflow.com/questions/34663785/c-operator-overload –

回答

0

解決方案:不要顯式聲明模板,它們會自動生成。也許有人可以更詳細地解釋爲什麼?

friend 
Matrix operator+(const Matrix& a, const Matrix& b) 
{ 
    if(a._m == b._m && a._n == b._n) 
    { 
     Matrix ret(a._m, a._n); 

     return ret; 
    } 
    else 
    { 
     throw "Matrix dimension mismatch error"; 
    } 
} 
2

首先,我想告訴超載+=代替,那麼在+=方面寫+。其次,朋友不應該是典型的模板。

template<typename T> 
class Matrix 
{ 
    friend Matrix operator+(Matrix a, const Matrix& b) { 
    a += b; 
    return std::move(a); 
    } 
    friend Matrix& operator+=(Matrix& a, const Matrix& b) { 
    a.increase_by(b); 
    return a; 
    } 
protected: 
    void increase_by(const Matrix& other); 

    size_t _m = 0 
    size_t _n = 0; 
    std::vector<T> _alloc; 
}; 

template<class T> 
void Matrix<T>::increase_by(const Matrix<T>& other) { 
    if(this->_m == other._m && this->_n == other._n) { 
    for (auto i = 0; i < _m*_n; ++i) { 
     _alloc[i] += other._alloc[i]; 
    } 
    // ... 
    } else { 
    throw "Matrix dimension mismatch error"; 
    } 
} 

注意上面的,具有高效的舉動,會給你合理有效a+b+c+d+e,爲創建LHS一次,屢遷。

+1

'返回的std ::移動(一) ;'爲什麼這個舉動?無論如何,返回值都是一個右值。 –

+0

@BaummitAugen RVO不會出現,明確的'移動'提醒我。 – Yakk

+1

這是爲什麼?爲什麼不能'自動c = a + b;'對於矩陣'a'和'b'沒有'move'沒有觸發RVO? –

2

您可以使用成員函數或非成員函數重載+運算符。

當它是一個成員函數時,運算符的LHS是函數將被調用的對象,而運算符的RHS是該函數的參數。因此,成員函數的唯一參數是RHS。

當它是成員函數時,運算符的LHS是該函數的第一個參數,而運算符的RHS是該函數的第二個參數。

成員函數

template<typename T> 
class Matrix 
{ 
    Matrix operator+(const Matrix& rhs) const { 
    ... 
    } 
}; 

如果你想實現它的類定義之外,你可以使用:

template<typename T> 
    Matrix<T> Matrix<T>::operator+(const Matrix& rhs) const { 
    ... 
    } 

非成員函數

template<typename T> 
class Matrix 
{ 
    Matrix operator+(const Matrix& lhs, const Matrix& rhs) { 
    ... 
    } 
}; 

如果你w螞蟻來實現它的類定義之外,你需要添加一些前瞻性聲明代碼:

// Forward declare the class template 
template <typename T> class Matrix; 

// Declare the function 
template <typename T> Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs); 

// Declare the friend in the class definition 
template <typename T> 
class Matrix 
{ 
    friend Matrix operator+<T>(const Matrix& lhs, const Matrix& rhs); 
    //      ^^^^ 
    // This makes operator+<int> a friend of Matrix<int>, not a friend 
    // of Matrix<double> 
}; 

,然後實現功能

template <typename T> Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs) 
{ 
    ... 
} 

採用這種設置,oprator+<int>Matrix<int>一個朋友而已,不是friendMatrix<double>

如果使用

template <typename U> 
friend 
Matrix<U> operator+(const Matrix<U>& a, const Matrix<U>& b); 

屆時,operator+所有實例都是Matrix所有實例,你並不需要的朋友。

更新

樣品工作代碼:

#include <iostream> 

// Forward declare the class template 
template<typename T> class Matrix; 

// Declare the function 
template <typename T> Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs); 

// Declare the friend in the class definition 
template <typename T> 
class Matrix 
{ 
    friend Matrix operator+<T>(const Matrix& lhs, const Matrix& rhs); 
    //      ^^^^ 
    // This makes operator+<int> a friend of Matrix<int>, not a friend 
    // of Matrix<double> 
}; 

template <typename T> Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs) 
{ 
    return Matrix<T>{}; 
} 

int main() 
{ 
    Matrix<int> a; 
    Matrix<int> b; 
    Matrix<int> c = a + b; 
} 
+0

我的前進宣言'模板矩陣'給出了錯誤'錯誤:矩陣不命名一個類型' – user3728501

+0

對不起,這應該只是'矩陣'。 –

+0

仍然有同樣的錯誤。 'Matrix'沒有命名一個類型 – user3728501