考虑2种类型的数组声明:
T x [rows * cols]; // type 1
T y [rows][cols]; // type 2
我通常使用第一种类型(类型1)然后我知道使用x [row * cols + col]进行索引
但是,如果我想将2d数组复制到模拟2d数组的1d数组中,即:copy type2 - > 1类。如果保证在内存中以相同的方式布置这些,我可以只对其中一个做一个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_;
答案 0 :(得分: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];
在这个例子中,它们是不同的。
答案 1 :(得分:2)
2d数组(您声明的那种)保证在内存中是连续的。这并不意味着你应该使用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
即可。然后,您不必实现复制构造函数,赋值运算符或析构函数。 (你已经实现了所有这三个,对吗?)