0

考虑 2 种类型的数组声明:

T x [rows * cols];  // type 1
T y [rows][cols];   // type 2

我通常使用第一种类型(类型 1),然后我知道使用 x[row * cols + col] 进行索引

但是,如果我想将二维数组复制到模拟二维数组的一维数组中,即:复制 type2 -> type1。如果保证这些在内存中的布局方式相同,我可以只对另一个进行 memcpy 吗?目前我有一个这样的循环,但如果内存在两者中的布局相同,我想我可以做一个 memcpy。考虑下面的公共构造函数。

public:
  // construct a matrix from a 2d array
  template <unsigned int N, unsigned int M>
  Matrix ( T (&twoDArray)[N][M]  )  : rows_(N), cols_(M), matrixData_(new T[rows_*cols_]) 
  {
    // is there a refactor here? Maybe to memcpy?
    for ( unsigned int i = 0; i < rows_ ; ++i )
    {
      for ( unsigned int j = 0; j < cols_ ; ++j )
      {
        matrixData_[ i * cols_ + j ] = twoDArray[i][j];
      }
    }
  }

  private:
  unsigned int rows_;
  unsigned int cols_;
  T* matrixData_;
4

2 回答 2

3

这取决于,但通常编译器会使简单的 T x[rows][columns] 表现得像 T x[rows * columns。除非你像动态声明内存

T** x = new T*[rows];
for (int i = 0; i < rows; ++i)
    x[i] = new T[columns];

在这个例子中,它们是不同的。

于 2013-08-24T02:14:38.147 回答
2

二维数组(您声明的那种)保证在内存中是连续的。这并不意味着您应该在其上使用 memcpy。尤其是不像你正在做的模板,因为 memcpy 可能无法正常工作T。你可以保留你所拥有的。不过,我可能会这样写(如果你不能使用 C++11,那么只需使用常规计数 for 循环):

template <unsigned int N, unsigned int M>
Matrix ( T (&twoDArray)[N][M]  )  : rows_(N), cols_(M), matrixData_(new T[rows_*cols_]) 
{
    T * out = matrixData_;
    for (auto const & sub : twoDArray)
        out = std::copy(std::begin(sub), std::end(sub), out);
}

或者更好的是,只需使用std::vector. 然后,您不必实现复制构造函数、赋值运算符或析构函数。(你已经实现了这三个,对吧?)

于 2013-08-24T02:30:00.533 回答