代码之家  ›  专栏  ›  技术社区  ›  Vedant Yadav

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

  •  0
  • Vedant Yadav  · 技术社区  · 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<T> 进入 Matrix<P> 。当我试图转换 Matrix<int> Matrix<float> 在我的test.cpp中使用以下代码:

      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_ private 在上下文中:

    m.arr_[i][j] = static_cast<P>(this->arr_[i][j]);
    
    1 回复  |  直到 1 年前
        1
  •  3
  •   wohlstad    1 年前

    你的主要问题是 Matrix<T1> Matrix<T2> (适用于类型 T1 , T2 不同且不相关的类型 .

    因此 矩阵<T1> 无法访问私人成员 在里面 矩阵<T2> ,这就是您所得到的错误的来源 arr_ 在这条线上是私人的:

    m.arr_[i][j] = static_cast<P>(this->arr_[i][j]);
    

    您可以通过以下两种方式解决此问题:

    1. 将公共访问器(setter、getter)添加到 Matrix ,并将其用于的实施 operator P() 而不是访问私有 arr_ .
      在我看来,这是最好的解决方案,因为类的用户可能无论如何都需要访问器方法来访问数据。

    2. 如果您有充分的理由避免添加访问者,并且由于您似乎只支持 Matrix<int> , Matrix<double> , Matrix<float> (基于您的 if constexpt ),那么你可以把这三个班交为朋友:

      friend Matrix<int>;
      friend Matrix<double>;
      friend Matrix<float>;
      

      这将使您能够访问私人 arr_ .


    代码中的另一个问题是 P 是整体的类型 Matrix<X> (对于某些类型 X 而不是元素的类型 在中 矩阵 .
    因此,这两行是错误的:

    Matrix<P> m(this->rows_, this->cols_);
    

    m.arr_[i][j]=static_cast<P>(这->arr_[i][j]);
    

    因为他们都认为 P 中元素的类型 矩阵 .

    要解决此问题,可以在中添加类型别名 矩阵 (公开可能很有用):

    template <typename T> class Matrix {
    public:
        using element_type = T;
    
        // ...
    };
    

    然后在上面的两行中使用它:

    Matrix<P::element_type> m(...);
    

    ... = static_cast<P::element_type>(...);
    

    笔记 您可能需要使用 typename P::element_type 而不是 P::element_type (如果您的C++版本早于C++20)。