我用c++做了一个矩阵类
namespace LinAlg {
template <typename T> class Matrix {
public:
Matrix();
Matrix(const uint64_t &rows, const uint64_t &cols);
template <typename P> operator P() const;
private:
uint64_t rows_, cols_;
std::vector<std::vector<T>> arr_;
};
template <typename T> template <typename P> Matrix<T>::operator P() const {
if constexpr (std::is_same_v<P, Matrix<int>> ||
std::is_same_v<P, Matrix<double>> ||
std::is_same_v<P, Matrix<float>>) {
Matrix<P> m(this->rows_, this->cols_);
for (uint64_t i = 0; i < this->rows_; i++) {
for (uint64_t j = 0; j < this->cols_; j++) {
m.arr_[i][j] = static_cast<P>(this->arr_[i][j]);
}
}
return m;
}
throw std::invalid_argument("Not a valid type conversions\n");
}
} // namespace LinAlg
我实现了 Matrix 到 Matrix 的类型转换
。当我尝试使用以下代码在 test.cpp 中将 Matrix 转换为 Matrix 时:
LinAlg::Matrix<int> M(3, 3);
std::cin >> M;
LinAlg::Matrix<float> M1(3, 3);
std::cin >> M1;
std::cout << static_cast<LinAlg::Matrix<float>>(M) + M1 << "\n";
我收到类似 arr_ is private in the context 的错误
m.arr_[i][j] = static_cast<P>(this->arr_[i][j]);
您的主要问题是
Matrix<T1>
和Matrix<T2>
(对于类型T1
,T2
)是不同且不相关的类型。
因此
Matrix<T1>
无法访问 Matrix<T2>
中的私有成员,这就是您收到的关于
arr_
是私有的错误的来源。
您可以通过两种方式克服这个问题:
向
Matrix
添加公共访问器(setter、getter),并在 operator P()
的实现中使用它们,而不是访问私有 arr_
。如果您有充分的理由避免添加访问器,并且由于您似乎只支持
Matrix<int>
、Matrix<double>
、Matrix<float>
(基于您的 if constexpt
),那么您可以将这 3 个类成为朋友:
friend Matrix<int>;
friend Matrix<double>;
friend Matrix<float>;
这将使您能够访问私人
arr_
。
代码中的另一个问题是
P
是整个 Matrix<X>
的类型(对于某些类型 X
,而不是 Matrix
中元素的类型。
因此这两行是错误的:
Matrix<P> m(this->rows_, this->cols_);
并且:
m.arr_[i][j] = static_cast<P>(this->arr_[i][j]);
因为他们都假设
P
是 Matrix
中元素的类型。
要解决这个问题,您可以在`Matrix:
中添加公共类型别名using element_type = T;
然后在上面两行中使用它:
Matrix<P::element_type> m(...);
并且:
... = static_cast<P::element_type>(...);