繁体   English   中英

C++ 部分特化好友声明 - 模板矩阵 class

[英]C++ Partial specialization friend declaration - template Matrix class

我创建了一个矩阵 class 如下:

template<typename T, unsigned N, unsigned M>
class Matrix {
public:

    template <unsigned P>
    Matrix<T,N,P> operator*(const Matrix<T,M,P>& other) const {
        Matrix<T,N,P> result;

        for(auto i = 0; i < N; i++) {
            for(auto j = 0; j < P; j++) {
                for(auto k = 0; k < M; k++) {
                    result.data[i][j] += data[i][k] * other.data[k][j];
                }
            }
        }

        return result;
    }

/* ... other members ... */

private:
    std::array<std::array<T, M>, N> data;
};

我现在遇到的问题是我无法访问other.data因为它是另一个 class (其他维度)的私有成员。 我尝试将operator*声明为这样的非会员朋友:

template<typename T, unsigned N, unsigned M>
class Matrix {
public:
    template <typename Type, unsigned RowA, unsigned ColA, unsigned ColB>
    Matrix<Type, RowA, ColB> friend operator*(const Matrix<Type, RowA, ColA>& a, const Matrix<Type, RowA, ColB>& b);

/* ... */

};

template <typename Type, unsigned RowA, unsigned ColA, unsigned ColB>
Matrix<Type, RowA, ColB>  operator*(const Matrix<Type, RowA, ColA>& a, const Matrix<Type, RowA, ColB>& b) {
    Matrix<Type, RowA, ColB> result;

    for(auto i = 0; i < RowA; i++) {
        for(auto j = 0; j < ColB; j++) {
            for(auto k = 0; k < ColA; k++) {
                result.data[i][j] += a.data[i][k] * b.data[k][j];
            }
        }
    }

    return result;
}

但它不起作用 - 编译器抱怨它找不到operator*的有效重载。

我在这里还有哪些其他选择? 解决方案是将所有具有兼容维度的矩阵声明为朋友,但这将是部分模板专业化,据我所知这是不可能的。 像这样的东西:

template<typename T, unsigned N, unsigned M>
class Matrix {
public:
    template<typename P>
    friend class Matrix<T,P,N>;
    
    /* ... */
};

我无法更改存储数据或Matrix模板 arguments 的方式 - 这是我得到的任务。

我在这里还有哪些其他选择?

恕我直言,您最好的选择是为矩阵添加公共访问方法,如下所示

T const & at (unsigned i, unsigned j) const // <-- read only version
 { return data[i][j]; }                     //     for const objects

T & at (unsigned i, unsigned j) // <-- read and write version
 { return data[i][j]; }

所以你的operator*() (外部版本)的核心变成

result.at(i, j) += a.at(i, k) * b.at(k, j);

并且不需要声明friend什么。

无论如何,您的外部operator*()的签名是错误的:应该是

template <typename T, unsigned Row, unsigned Mid, unsigned Col>
Matrix<T, Row, Col>  operator* (Matrix<T, Row, Mid> const & a,
                                Matrix<T, Mid, Col> const & b)

您在第二个参数中使用RowA而不是ColA作为第一个维度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM