0

次の 2 種類の配列宣言を考えてみましょう。

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

私は通常、最初のタイプ (タイプ 1) を使用し、x[row * cols + col] を使用してインデックスを作成することを知っています。

ただし、2 次元配列をシミュレートする 1 次元配列に 2 次元配列をコピーしたい場合、つまり、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

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。その後、コピー コンストラクター、代入演算子、またはデストラクターを実装する必要はありません。(これらの 3 つすべてを実装しましたよね?)

于 2013-08-24T02:30:00.533 に答える