C++中用户定义类的类型转换

问题描述 投票:0回答:1

我用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]);

c++ class templates type-conversion
1个回答
0
投票

您的主要问题是

Matrix<T1>
Matrix<T2>
(对于类型
T1
T2
)是不同且不相关的类型

因此

Matrix<T1>
无法访问 Matrix<T2>
 中的私有成员
,这就是您收到的关于
arr_
是私有的错误的来源。

您可以通过两种方式克服这个问题:

  1. Matrix
    添加公共访问器(setter、getter),并在
    operator P()
    的实现中使用它们,而不是访问私有
    arr_

    在我看来,这似乎是最好的解决方案,因为该类的用户可能无论如何都需要访问器方法来访问数据。

  2. 如果您有充分的理由避免添加访问器,并且由于您似乎只支持

    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>(...);
© www.soinside.com 2019 - 2024. All rights reserved.