2016-03-07 115 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