在Matlab中,可以重塑'从任何维度到任何其他维度的(N维)矩阵,只要元素的数量不变。那就是:
A = rand(10,10);
B = reshape(A, 100, 1);
Matlab可以非常高效地完成这项任务,因为A和B仍指向100个双打的同一个块,只有在写入A或B时才复制它们:这称为写时复制。
我想在C / C ++中使用这种重塑功能,也就是说,我希望能够做到这一点:
double flat[100];
double square[10][10] = ... flat ...;
这样,square代表相同的数据,但解释器以另一种方式索引。
最后,我想要的是语法糖,做square [i] [j]而不是square [10 * i + j]。所以,是的,编写一些能够与不同维度共享数据的类(如matlab一样)重载索引运算符可以做yob。但是,我正在寻找一个更简单的解决方案。
另一方面,我担心C ++标准允许编译器以不同的方式实现维数阵列,不允许我想要的东西。例如,int [10] [10]可以实现为10个双精度的10个块和10个指向那些的双指针的一个块。而且,我自己可以创造这样的东西:
double **blowUp(double *array, int m, int n) {
double **r = new double[m];
for(int i=0; i<m; ++i, array+=n) r[i] = array;
return r;
}
然后语法糖的想法消失了一点,特别是因为我还需要清理包装器数组。
另一种解决方案可能是模板化的下标运算符重载,其中模板参数包含数据的第一维:
但是,正如编译错误所示,如果不将数据包装在类结构中,这是不可行的。所以,如果我想要我想要的东西,我注定要在一个类中包装数据并编写很多样板代码吗?请让我知道你的想法!
答案 0 :(得分:4)
如果你使用的是一个简单的数组,使用reinterpret_cast
就很容易了。举个例子:
#include <iostream>
int main()
{
int flat[100];
for (int i=0; i<100; ++i)
flat[i]=i;
// now reinterpret that flat array as a 10x10 square
int (&square)[10][10] = *reinterpret_cast<int(*)[10][10]>(flat);
// print an arbitrary row
for (int i=0; i<10; ++i)
std::cout << square[5][i] << ' ';
std::cout << '\n';
}
这个简单的程序打印:
50 51 52 53 54 55 56 57 58 59
答案 1 :(得分:2)
最简单的方法是将平面数组包装在一个类中。您可以实现use operator[]
以返回指向i th 行的指针。此operator[]
的实现需要知道您希望对基础数组施加的形状。