代码之家  ›  专栏  ›  技术社区  ›  Evandro Coan

错误:“long int(*)[4]”到“long int[4][4]”的赋值中的类型不兼容

  •  0
  • Evandro Coan  · 技术社区  · 8 年前

    我正在努力建立自己的 Matrix 作为标准行的类型 C 具有多维数组的矩阵。到目前为止,这是我的实现:

    #include <iostream>
    
    /**
     * To build it use:
     *     g++ -std=c++11 test_template_initicialization.cpp -o main
     */
    template <int width, int height>
    struct Matrix
    {
      long int _data[height][width];
    
      Matrix()
      {
      }
    
      Matrix(long int matrix[height][width]) : _data(matrix)
      {
      }
    
      /**
       * Overloads the `[]` array access operator, allowing you to access this class objects as the
       * where usual `C` arrays.
       *
       * @param  line the current line you want to access
       * @return      a pointer to the current line
       */
      long int* operator[](int line)
      {
        return this->_data[line];
      }
    
      /**
       * Prints a more beauty version of the matrix when called on `std::cout<< matrix << std::end;`
       */
      friend std::ostream &operator<<( std::ostream &output, const Matrix &matrix )
      {
        int i, j;
    
        for( i=0; i < height; i++ )
        {
          for( j=0; j < width; j++ )
          {
            output << matrix._data[i][j] << ", ";
          }
    
          output << matrix._data[i][j] << "\n";
        }
        return output;
      }
    };
    
    /**
     * C++ Matrix Class
     * https://stackoverflow.com/questions/2076624/c-matrix-class
     */
    int main (int argc, char *argv[])
    {
      Matrix<3, 3> matrix;
      std::cout << matrix << std::endl;
    
      matrix[0][0] = 911;
      std::cout << matrix << std::endl;
    
      std::cout << matrix[0] << std::endl;
      std::cout << matrix[0][0] << std::endl;
    
      Matrix<4,4> matrix2 = { 0 };
    }
    

    构建最后一个示例时 Matrix<4,4> matrix2 = { 0 }; 我收到不兼容类型错误:

    D:\test_template_initicialization.cpp: In instantiation of 'Matrix<width, height>::Matrix(long int (*)[width]) [with int width = 4; int height = 4]':
    D:\test_template_initicialization.cpp:67:29:   required from here
    D:\test_template_initicialization.cpp:16:56: error: incompatible types in assignment of 'long int (*)[4]' to 'long int [4][4]'
       Matrix(long int matrix[height][width]) : _data(matrix)
    

    错误的主要部分是 'long int (*)[4]' to 'long int [4][4]' . 这个 long int (*)[4] 来自 matrix2 = { 0 }; 以及 long int [4][4] 是我的标准类模板声明 long int _data[height][width];

    我能修好我的 矩阵 构造函数,所以它可以接受 长整型(*)[4] 来自 矩阵2={0}; 初始化调用?

    1 回复  |  直到 8 年前
        1
  •  0
  •   Evandro Coan    8 年前

    我通过以下链接成功修复了它:

    1. http://en.cppreference.com/w/cpp/utility/initializer_list
    2. Invalid Conversion from 'int' to 'int(*)[3]' c++
    3. Using multidimensional std::initializer_list
    4. Brace-enclosed initializer list constructor
    5. C++ Matrix Class
    6. Does java have an equivalent to python __call__?
    7. C++ Functors - and their uses
    8. Return array in a function
    9. When using C headers in C++, should we use functions from std:: or the global namespace?
    10. What happened to std::assert
    11. There are no arguments that depend on a template parameter
    12. Optional Template parameter

    固定代码:

    #include <cassert>
    #include <iostream>
    
    template <unsigned int array_width, typename array_datatype=long int>
    struct Array
    {
      array_datatype _data[array_width];
    
      Array()
      {
      }
    
      Array(std::initializer_list< array_datatype > raw_data)
      {
        unsigned int data_size = raw_data.size();
        unsigned int column_index = 0;
        // std::cout << data_size << std::endl;
    
        if( data_size == 1 )
        {
          array_datatype initial = *(raw_data.begin());
    
          for( ; column_index < array_width; column_index++ )
          {
            this->_data[column_index] = initial;
          }
        }
        else
        {
          assert(data_size == array_width);
    
          for( auto column : raw_data )
          {
            this->_data[column_index] = column;
            column_index++;
          }
        }
      }
    
      /**
       * Overloads the `[]` array access operator, allowing you to access this class objects as the
       * where usual `C` arrays.
       *
       * @param  line the current line you want to access
       * @return      a pointer to the current line
       */
      array_datatype* operator[](int line)
      {
        return this->_data;
      }
    
      /**
       * Prints a more beauty version of the matrix when called on `std::cout<< matrix << std::end;`
       */
      friend std::ostream &operator<<( std::ostream &output, const Array &matrix )
      {
        unsigned int column;
        output << "{";
    
        for( column=0; column < array_width; column++ )
        {
          output << matrix._data[column];
    
          if( column != array_width-1 )
          {
            output << ", ";
          }
        }
    
        output << "}";
        return output;
      }
    };
    
    
    template <unsigned int matrix_width, unsigned int matrix_height, typename matrix_datatype=long int>
    struct Matrix
    {
      matrix_datatype _data[matrix_height][matrix_width];
    
      Matrix()
      {
      }
    
      Matrix(matrix_datatype initial)
      {
        unsigned int line;
        unsigned int column;
    
        for( line=0; line < matrix_height; line++ )
        {
          for( column=0; column < matrix_width; column++ )
          {
            this->_data[line][column] = initial;
          }
        }
      }
    
      Matrix(std::initializer_list< std::initializer_list< matrix_datatype > > raw_data)
      {
        // std::cout << raw_data.size() << std::endl;
        assert(raw_data.size() == matrix_height);
    
        // std::cout << raw_data.begin()->size() << std::endl;
        assert(raw_data.begin()->size() == matrix_width);
    
        unsigned int line_index = 0;
        unsigned int column_index;
    
        for( auto line : raw_data )
        {
          column_index = 0;
    
          for( auto column : line )
          {
            this->_data[line_index][column_index] = column;
            column_index++;
          }
    
          line_index++;
        }
      }
    
      /**
       * Overloads the `[]` array access operator, allowing you to access this class objects as the
       * where usual `C` arrays.
       *
       * @param  line the current line you want to access
       * @return      a pointer to the current line
       */
      matrix_datatype* operator[](int line)
      {
        return this->_data[line];
      }
    
      /**
       * Prints a more beauty version of the matrix when called on `std::cout<< matrix << std::end;`
       */
      friend std::ostream &operator<<( std::ostream &output, const Matrix &matrix )
      {
        unsigned int line;
        unsigned int column;
        output << "{";
    
        for( line=0; line < matrix_height; line++ )
        {
          output << "{";
    
          for( column=0; column < matrix_width; column++ )
          {
            output << matrix._data[line][column];
    
            if( column != matrix_width-1 )
            {
              output << ", ";
            }
          }
    
          if( line != matrix_height-1 )
          {
            output << "}, ";
          }
          else
          {
            output << "}";
          }
        }
    
        output << "}";
        return output;
      }
    };
    
    
    void array_tests()
    {
      std::cout << "Array tests" << std::endl;
      Array<3, long int> array;
    
      std::cout << array << std::endl;
      std::cout << array[0] << std::endl;
    
      Array<3> array2 = {0,0,0};
      std::cout << "array2: " << array2 << std::endl;
    
      Array<3> array3 = {3};
      std::cout << "array3: " << array3 << std::endl;
    }
    
    
    void matrix_tests()
    {
      std::cout << "Matrix tests" << std::endl;
      Matrix<3, 3, long int> matrix;
      std::cout << matrix << std::endl;
    
      matrix[0][0] = 911;
      std::cout << matrix << std::endl;
    
      std::cout << matrix[0] << std::endl;
      std::cout << matrix[0][0] << std::endl;
    
      Matrix<3, 3> matrix2{ {0,0,0}, {0,0,0}, {0,0,0} };
      std::cout << matrix2 << std::endl;
    
      Matrix<3, 3> matrix3 = { 3 };
      std::cout << matrix3 << std::endl;
    
      Matrix<3, 1, long int> matrix4 = { 4 };
      std::cout << matrix4 << std::endl;
    }
    
    
    /**
     * To build it use:
     *     g++ -std=c++11 main.cpp -o main
     */
    int main (int argc, char *argv[])
    {
      matrix_tests();
      std::cout << std::endl;
      array_tests();
    }
    

    运行此功能,您将获得:

    Matrix tests
    {{4200800, 0, -928274330}, {32765, 14354248, 0}, {-1499063668, 0, 24}}
    {{911, 0, -928274330}, {32765, 14354248, 0}, {-1499063668, 0, 24}}
    0x65fde0
    911
    {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}
    {{3, 3, 3}, {3, 3, 3}, {3, 3, 3}}
    {{4, 4, 4}}
    
    Array tests
    {0, 1875566066, 0}
    0x65fdf4
    array2: {0, 0, 0}
    array3: {3, 3, 3}