# matrixarray

• December 1st, 2012, 11:29 PM
aamir121a
matrixarray
I wish to convert a 2D Array i.e int a[20][20] , convert to either s single array as in in[400] or hold it in a vector , and then back again , any ideas ?
my initial thoughts were

Code:

```for(a to 200) for(b to 200) {   vector.push.back(int[a][b]); // this in sudo code ; }```
• December 2nd, 2012, 01:57 AM
Paul McKenzie
Re: matrixarray
Quote:

Originally Posted by aamir121a
I wish to convert a 2D Array i.e int a[20][20] , convert to either s single array as in in[400] or hold it in a vector , and then back again , any ideas ?

Code:

```#include <algorithm> #include <vector> template <typename T> struct VectorFrom2DArrayInitializer {     typedef std::vector<T> TVector;     TVector & m_v;     int m_nElements;     VectorFrom2DArrayInitializer(TVector& theVector, int numElements) :                 m_v(theVector), m_nElements(numElements) {}     void operator()(T *pElements)     {  m_v.insert(m_v.end(), pElements, pElements + m_nElements); } }; template <typename T, int Rows, int Cols> void Init1DVectorFrom2DArray(std::vector<T>& v, T arr[Rows][Cols]) { std::for_each(arr, arr + Rows, VectorFrom2DArrayInitializer<T>(v, Cols)); } int main() {     // Initialize array to something     int a[20][20];     int counter = 0;     for (int i = 0; i < 20; ++i)         for (int j = 0; j < 20; ++j)             a[i][j] = counter++;     // set vector to the above array     std::vector<int> v;     Init1DVectorFrom2DArray<int, 20, 20>(v, a); }```
Well, this uses no loops except for the initializer for the array at the beginning of the test main() program.

It now doesn't matter if it's a 2d array of int, char, double, or Widgets. The 2d array of T is copied to the 1d vector of T using for_each() and a function object. Note that the only reliance on "int" is in the template argument to the Init1DVectorFrom2DArray function. Then everything there relies on type T, regardless of what T is.

Regards,

Paul McKenzie
• December 2nd, 2012, 06:14 AM
nuzzle
Re: matrixarray
Quote:

Originally Posted by aamir121a
, any ideas ?

Instead of copying the arrays you can "overlay" them using a union,

Code:

```union Same {   int a[50];   int b[10][5]; };```
Here a and b represent the same 50 consecutive ints of memory, only they are accessed according to different matrix abstractions (and more can be added).

Code:

```Same same; // static allocation at compile time // same.b[2][3] = 42; std::cout << same.a[13] << std::endl;```
It works because b[2][3] and a[13] represent the same memory position (2*5 + 3 = 13).

Since std::vector allocates memory dynamically a pointer must be used in that case. The above becomes,

Code:

```std::vector<int> v(50); // dynamic allocation at runtime Same* same = reinterpret_cast<Same*>(&v[0]); // sets Same pointer to start of vector data // same->b[2][3] = 42; std::cout << same->a[13] << std::endl; std::cout << v[13] << std::endl;```
• December 4th, 2012, 06:41 PM
aamir121a
Re: matrixarray
thank you
• December 5th, 2012, 02:04 AM
superbonzo
Re: matrixarray
Quote:

Originally Posted by nuzzle
they are accessed according to different matrix abstractions (and more can be added).

I think this is not advisable; that use of unions relies on specific guarantees related to not-so-manifest properties of the types involved. Even with POD's you have to make sure that those member types have the same memory layout. Yes, with C++11 things have been relaxed to allow standard memory layout types with compatible layouts ( so, say, you could put there an std::array ) but it's still non trivial to check that the code is actually portable. So, I'd leave this technique to implementation details only.
• December 5th, 2012, 06:19 AM
nuzzle
Re: matrixarray
Quote:

Originally Posted by superbonzo
So, I'd leave this technique to implementation details only.

With different matrix abstractions I meant variations of 50 consecutive ints, like say

Code:

```union Same {   int a[50];   int b[10][5];   int c[25][2];   int d[2][5][5]; // etcetera };```
To the best of my knowledge my suggestion is portable according to the C++ 11 standard (both regarding memory layout and the use of the reinterpret_cast).

But I agree that C-ish stuff like this shouldn't be all over the place in a C++ program.
• December 5th, 2012, 11:43 AM
OReubens
Re: matrixarray
alternatvively... "why does it matter" ?
The data will ultimately be stored similarly, why does your code need to make a difference between 2D (or xD for that matter) or flat (1D) ?

If you have a need for a container that allows your data to be approached "flat" as well as 2d or 3d, then why not simply make a container like that. Make a template class that takes 2 dimentions, use it to make a X*Y vector, then provide members that can access the data either flat (with 1 index) or as a 2D array (with 2 indexes) (or as a 3D, 4D..... whatever).
• December 6th, 2012, 03:47 AM
JohnW@Wessex
Re: matrixarray
Quote:

Originally Posted by OReubens
If you have a need for a container that allows your data to be approached "flat" as well as 2d or 3d, then why not simply make a container like that.

Yes, that's the way I'd approach it.