代码之家  ›  专栏  ›  技术社区  ›  Hejun

使用Cuffic函数操作C++中模板类中的私有变量时出错

  •  1
  • Hejun  · 技术社区  · 7 年前

    我最近正在写一个矩阵运算库,我想在程序中重载运算符s,但是当我使用friend函数访问我定义的模板类中的私有变量时出错了。(而且它只在重载运算符“+”时报告错误,而重载操作“-”的函数不报告错误。) 我定义的模板类如下:

    template<class T>
    class Matrix
    {
        int col;
        int row;
        T *matrix;
        public:
            Matrix(T *m, int row1, int col1):matrix(m), row(row1), col(col1){}
            Matrix(int row1, int col1):row(row1), col(col1)
            {
                matrix = new T[row*col];
                cout<<"Have set the shape of the matrix, but should use create() to initialize the matrix!"<<endl;
            }
            Matrix(){}
            ~Matrix(){}
            void show();
            UINT create(T *m);
            UINT zeros(int size);
            UINT eye(int size);
    
            // the overload function statement
            friend Matrix operator+(const Matrix &a, const Matrix &b);
            friend Matrix operator-(const Matrix &a, const Matrix &b);
    
            Matrix matrix_T();              // transpose the matrix
            Matrix matrix_Inv();            // calculate matrix's inverse
            Matrix matrix_Adjoint();        // calculate the adjoint matrix
    };
    

    这两个重载函数的定义如下:

    // report error: can't access private member declared in class
    template<class T>
    Matrix<T> operator +(const Matrix<T> &m1, const Matrix<T> &m2)
    {
        if (m1.col!=m2.col || m1.row!=m2.row)
        {
            cout<<"These two matrices can't be plused!"<<endl;
            exit(0);
        }
        T *tmp = new T[m1.col*m1.row];
        for (int i=0; i<m1.row; i++)
        {
            for (int j=0; j<m1.col; j++)
            {
                tmp[i*m1.col+j] = m1.matrix[i*m1.col+j] + m2.matrix[i*m1.col+j];
            }
        }
        return Matrix<T>(tmp, m1.row, m1.col);
    }
    
    
    // this defination didn't report error
    // and if I only run this code, there is nothing wrong
    template<class T>
    Matrix<T> operator -(const Matrix<T> &m1, const Matrix<T> &m2)
    {
        if (m1.col!=m2.col || m1.row!=m2.row)
        {
            cout<<"These two matrices can't be plused!"<<endl;
            exit(0);
        }
        T *tmp = new T[m1.col*m1.row];
        for (int i=0; i<m1.row; i++)
        {
            for (int j=0; j<m1.col; j++)
            {
                tmp[i*m1.col+j] = m1.matrix[i*m1.col+j] - m2.matrix[i*m1.col+j];
            }
        }
        return Matrix<T>(tmp, m1.row, m1.col);
    }
    

    我已经分别测试了这两段代码,运算符“-”的重载可以正确编译,但运算符“+”不能。 误差信息如下:

    f:\program\c++\matrixoperate\matrixdefine.h(134) : error C2248: 'col' : cannot access private member declared in class 'Matrix<int>'
        f:\program\c++\matrixoperate\matrixdefine.h(6) : see declaration of 'col'
        f:\program\c++\matrixoperate\demo.cpp(14) : see reference to function template instantiation 'class Matrix<int> __cdecl operator +(const class Matrix<int> &,const class Matrix<int> &)' being compiled
    f:\program\c++\matrixoperate\matrixdefine.h(134) : error C2248: 'col' : cannot access private member declared in class 'Matrix<int>'
        f:\program\c++\matrixoperate\matrixdefine.h(6) : see declaration of 'col'
    

    我使用的IDE是VC++ 6。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Yakk - Adam Nevraumont    7 年前

    friend Matrix operator+(const Matrix &a, const Matrix &b); 不是模板。它是模板类的非模板友元函数。

    template<class T>Matrix<T> operator +(const Matrix<T> &m1, const Matrix<T> &m2) 是一个模板。它们不是同一个函数,因为一个是模板,另一个不是。

    解决这个问题的最简单方法是将body内联到模板类定义中。

    第二个简单的方法是从 operator+ 到某个静态方法或某个命名函数模板。在模板类定义之前转发声明它,在模板类定义中友化它,在之后实现它。

    (你真的想要 操作员+ 成为一个模板类的非模板朋友,因为这使得它在转换方面表现得更好。)

    我也是 https://stackoverflow.com/a/13464246/1774667 但对于命名函数,不是运算符。称之为 add 是的。

    那么 friend Matrix operator+(const Matrix &a, const Matrix &b){ return add(a,b); } 这给了你模板类魔术的非模板朋友运算符。