In Matlab it is possible to 'reshape' a (N-dimensional) matrix from any dimension to any other dimension, as long as the number of elements does not change. That is:

A = rand(10,10);
B = reshape(A, 100, 1);

Matlab can do so quite efficiently, because A and B still point to the same block of 100 doubles, they are only copied if one writes to either A or B: this is called copy-on-write.

I want this reshape feature in C/C++, that is, I want to be able to do this:

double flat[100];
double square[10][10] = ... flat ...;

such that square represents the same data, but interpreters indexing in another way.

In the end, what I want is syntax sugar, to do square[i][j] instead of square[10*i+j]. So, yes, writing some class that is able to share data with different dimensions (like matlab does) overloading indexing operators may do the yob. However, I am looking for a simpler solution.

On the other hand, I am afraid that the C++ standard(s) allow for compilers to implement dimensional arrays in different ways, disallowing for what I want. For example int[10][10] may be implemented as 10 blocks on 10 doubles and one block of 10 double pointers pointing to those. Moreover, I can create such a thing myself:

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;
}

but then the idea of syntax sugar disappears a bit, especially since I would need to clean up the wrapper array as well.

Another solution may be a templated subscript operator overload, where the the template arguments contain the first dimension of the data:

http://ideone.com/aonHN2

But as the compile errors suggest, this is not feasible without wrapping the data in a class structure. So, am I doomed to wrap data in a class and write a lot of boilerplate code if I want what I want? Please let me know what you think!

有帮助吗?

解决方案

If you're using a simple array, this is quite easy using a reinterpret_cast. Taking your example:

#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';
}

This simple program prints:

50 51 52 53 54 55 56 57 58 59 

其他提示

The cleanest way to do this is to wrap the flat array in a class. You can implement use operator[] to return a pointer to the ith row. The implementation of this operator[] needs to know the shape which you wish to impose on the underlying array.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top