重载模板类二进制运算符*

时间:2014-01-16 16:17:55

标签: c++ templates c++11 operator-overloading

我正在编写一个2D矩阵模板来学习模板和一些C ++ 11的功能。

写下以下标题:

template <class T, unsigned int Rows, unsigned int Columns>
class Matrix2D
{
private:
    array<array<T,Columns>, Rows> m_Matrix;

public:
    Matrix2D() {}

    array<T,Columns>& operator[](unsigned int row)       { return m_Matrix[row]; } ;
    const array<T,Columns>& operator[](unsigned int row) const { return m_Matrix[row]; } ;

    friend Matrix2D operator+ <> (const Matrix2D &lhs, const Matrix2D &rhs);
    friend Matrix2D operator* <> (const Matrix2D &lhs, const Matrix2D &rhs);
};

operator+工作正常 - 我有一个实现,它编译,链接,并通过调试器。

问题在于operator*,我得到了编译错误

1>...\matrix2d.h(18): error C2143: syntax error : missing ';' before '<'
1>...\matrix2d.h(19) : see reference to class template instantiation 'Matrix2D<T,Rows,Columns>' being compiled

尝试使用运算符没有代码行,所以定义本身是错误的,我只是不明白为什么。

有人可以帮忙吗?

编辑 :( 从评论中添加

template <class T, unsigned int Rows, unsigned int Columns>
Matrix2D<T, Rows, Columns> operator+ (const Matrix2D<T, Rows, Columns> &lhs, const Matrix2D<T, Rows, Columns> &rhs)
{
    Matrix2D<T, Rows, Columns> addResult;
    for (unsigned int i = 0; i < Rows; i++)
        for (unsigned int j = 0; j < Columns; j++)
            addResult[i][j] = lhs[i][j] + rhs[i][j];
    return addResult;
}

template <class T, unsigned int Rows, unsigned int Columns>
Matrix2D<T, Rows, Columns> operator* (const Matrix2D<T, lRows, lColumns> &lhs, const Matrix2D<T, rRows, rColumns> &rhs)
{
    Matrix2D<T, lRows, rColumns> mulResult;

    for(unsigned int i = 0; i < lRows; i++)
        for(unsigned int j = 0; j < rColumns; j++)
            for (unsigned int k = 0; k < lColumns; k++)
                mulResult[i][k] += lhs[i][k] * rhs[k][j];
    return addResult;
}

2 个答案:

答案 0 :(得分:2)

您无法与未声明的模板功能进行专业化。当然,在定义类模板之前声明运算符将要求您转发声明它:

template <class T, unsigned int Rows, unsigned int Columns>
class Matrix2D;

template <class T, unsigned int Rows, unsigned int Columns>
Matrix2D<T, Rows, Columns>
operator+ (const Matrix2D<T, Rows, Columns> &lhs, const Matrix2D<T, Rows, Columns> &rhs);

template <class T, unsigned int Rows, unsigned int Columns>
Matrix2D<T, Rows, Columns>
operator* (const Matrix2D<T, Rows, Columns> &lhs, const Matrix2D<T, Rows, Columns> &rhs);

template <class T, unsigned int Rows, unsigned int Columns>
class Matrix2D
{
private:
    array<array<T,Columns>, Rows> m_Matrix;

public:
    Matrix2D() {}

    array<T,Columns>& operator[](unsigned int row)       { return m_Matrix[row]; }
    const array<T,Columns>& operator[](unsigned int row) const { return m_Matrix[row]; }

    friend Matrix2D operator+ <> (const Matrix2D &lhs, const Matrix2D &rhs);
    friend Matrix2D operator* <> (const Matrix2D &lhs, const Matrix2D &rhs);
};

或者,您可以采用简单的方法为Matrix2D的每个专业化定义单独的运算符函数:

template <class T, unsigned int Rows, unsigned int Columns>
class Matrix2D
{
private:
    array<array<T,Columns>, Rows> m_Matrix;

public:
    Matrix2D() {}

    array<T,Columns>& operator[](unsigned int row)       { return m_Matrix[row]; }
    const array<T,Columns>& operator[](unsigned int row) const { return m_Matrix[row]; }

    friend Matrix2D operator+ (const Matrix2D &lhs, const Matrix2D &rhs) {
        // do stuff that adds.
    }
    friend Matrix2D operator* (const Matrix2D &lhs, const Matrix2D &rhs) {
        // do stuff that multiplies.
    }
};

我可能会使用更简单的整体语法。

编辑:非正方形​​矩阵的正确乘法意味着operator*函数实际上需要成为Matrix2D的三个不同特化的朋友:左操作数的类型,右操作数和结果。我认为这里的第一种方法会变得站不住脚。您应该成为operator*的所有专精的朋友:

template <class T, unsigned int Rows, unsigned int Columns>
class Matrix2D
{
  // ...

  template <typename U, typename V, unsigned Rows, unsigned Common, unsigned Columns>
  friend Matrix2D<decltype(std::declval<U>()+std::declval<V>()), Rows, Columns>
  operator * (const Matrix2D<U, Rows, Common>&,
              const Matrix2D<V, Common, Columns>&);

};

或简单地公开数据(无论如何,这可能是“数据收集”类的最佳方法)。

答案 1 :(得分:1)

在:

template <class T, unsigned int Rows, unsigned int Columns>
class Matrix2D
{
    // ...
    friend Matrix2D operator* <> (const Matrix2D &lhs, const Matrix2D &rhs);
};

Matrix2D实际上是指Matrix2D<T, Rows, Columns>

您的operator *应该是

template <T, unsigned Rows1, unsigned int Common, unsigned int Column>
Matrix2D<T, Row1, Column> operator* (const Matrix2D<T, Row1, Common>& lhs, const Matrix2D<T, Common, Column>& rhs);