-1

I have this multidimensional 2 arrays

int anArray1[MAX_ROW][MAX_CELL] =
{
    { 0, 1, 1, 0, 1, 1, 1, 0},
    { 0, 1, 1, 0, 1, 1, 1, 0},
    { 0, 1, 1, 0, 1, 1, 1, 0},
    { 0, 1, 1, 0, 1, 1, 1, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0}
}


int anArray2[MAX_ROW][MAX_CELL] =
{
    { 0, 1, 1, 0, 1, 1, 1, 0},
    { 0, 1, 1, 0, 1, 1, 1, 0},
    { 0, 1, 1, 0, 1, 1, 1, 0},
    { 0, 1, 1, 0, 1, 1, 1, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0}
}

and i want to store them in index based container , i tryed to make another int array that supposed to hold them like this:

int LevelsArray[LEVELS_COUNT] = { anArray1, anArray2};

im getting this error:

error C2440: 'initializing' : cannot convert from 'int [68][8]' to 'int'

i guess this is not the correct way .. what is the recommended way ?

Erbureth
  • 3,378
  • 22
  • 39
user63898
  • 29,839
  • 85
  • 272
  • 514

3 Answers3

5

I wouldn't consider a plain old array a C++ container. I would rather use a combination of std::vector (or std::array), because of reasons.

Here's an example:

#include <iostream>
#include <vector>

typedef int cell;
typedef std::vector<cell> row;
typedef std::vector<row> level;
typedef std::vector<level> levels;

int main() {
    levels l = 
    {
        {
            { 0, 1, 1, 0, 1, 1, 1, 0},
            { 0, 1, 1, 0, 1, 1, 1, 0},
            { 0, 1, 1, 0, 1, 1, 1, 0},
            { 0, 1, 1, 0, 1, 1, 1, 0},
            { 0, 0, 0, 0, 0, 0, 0, 0}
        },
        {
            { 0, 1, 1, 0, 1, 1, 1, 0},
            { 0, 1, 1, 0, 1, 1, 1, 0},
            { 0, 1, 1, 0, 1, 1, 1, 0},
            { 0, 1, 1, 0, 1, 1, 1, 0},
            { 0, 0, 0, 0, 0, 0, 0, 0}
        },
    };
    for (int i = 0; i < l.size(); i++) {
        std::cout << "level " << i << ":\n" ;
        for (row & r : l[i]) {
            for (cell & c : r)
                std::cout << c << " ";
            std::cout << "\n";
        }
        std::cout << "\n";
    }
}

The output is:

$ g++ test.cc -std=c++11 && ./a.out
level 0:
0 1 1 0 1 1 1 0 
0 1 1 0 1 1 1 0 
0 1 1 0 1 1 1 0 
0 1 1 0 1 1 1 0 
0 0 0 0 0 0 0 0 

level 1:
0 1 1 0 1 1 1 0 
0 1 1 0 1 1 1 0 
0 1 1 0 1 1 1 0 
0 1 1 0 1 1 1 0 
0 0 0 0 0 0 0 0 

Using std::array instead could look something like this:

#include <iostream>
#include <vector>
#include <array>

const int cells_per_row = 8;
const int rows_per_level = 5;
const int nlevels = 2;
typedef int cell;
typedef std::array<cell, cells_per_row> row;
typedef std::array<row, rows_per_level> level;
typedef std::array<level, nlevels> levels;

int main() {
    levels l = 
    {
        level{
            row{ 0, 1, 1, 0, 1, 1, 1, 0},
            row{ 0, 1, 1, 0, 1, 1, 1, 0},
            row{ 0, 1, 1, 0, 1, 1, 1, 0},
            row{ 0, 1, 1, 0, 1, 1, 1, 0},
            row{ 0, 0, 0, 0, 0, 0, 0, 0}
        },
        level{
            row{ 0, 1, 1, 0, 1, 1, 1, 0},
            row{ 0, 1, 1, 0, 1, 1, 1, 0},
            row{ 0, 1, 1, 0, 1, 1, 1, 0},
            row{ 0, 1, 1, 0, 1, 1, 1, 0},
            row{ 0, 0, 0, 0, 0, 0, 0, 0}
        },
    };
    for (int i = 0; i < l.size(); i++) {
        std::cout << "level " << i << ":\n" ;
        for (row & r : l[i]) {
            for (cell & c : r)
                std::cout << c << " ";
            std::cout << "\n";
        }
        std::cout << "\n";
    }
}

Note that the examples make some use of C++11 features (initializer lists, range-based for, std::array) that may not be supported by every compiler. While you can work around the initializer lists to initialize the containers and the range-based for loop for printing, there's no std::array prior to C++11.

For reference:

Community
  • 1
  • 1
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • im getting initialization with '{...}' is not allowed for object of type "levels" on the vector example using visual studio 2012 – user63898 Feb 02 '15 at 13:07
  • also give me banch of error with the std::array example like: 'level' : illegal use of this type as an expression – user63898 Feb 02 '15 at 13:22
  • @user63898 `std::array` became part of C++ with the C++11 standard. You might need to check whether your compiler supports that feature or how you can enable it. (Same goes for the range-based-for loop I've used in the example.) I tested both examples with g++ 4.8.3. – moooeeeep Feb 02 '15 at 13:29
  • oo . so its not good i need something that support old compilers ( 2008 ) also – user63898 Feb 02 '15 at 13:37
  • so i guess if i want pure c++ i stack with the c 3d array – user63898 Feb 02 '15 at 13:40
  • see below comment the std vector makes me problem also when i try to initialize it – user63898 Feb 02 '15 at 13:55
  • 1
    @user63898 You need to learn about the options you have to initialize a `std::vector` without using initializer lists: http://stackoverflow.com/q/2236197/1025391 – moooeeeep Feb 02 '15 at 17:55
  • i know this answer thanks for remind me , so its basically dead end for simple solution i will go with simple 3d c int array – user63898 Feb 02 '15 at 19:26
1

You can use more explicit declaration of the LevelsArray type

int LevelsArray[LEVELS_COUNT][MAX_ROW][MAX_CELL] = { {...}, {...} };

However the C++ way would be to use std::vector or std::array (requires C++11):

std::vector<std::vector<std::vector<int>>> LevelsArray =
{
    {
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 0, 0, 0, 0, 0, 0, 0}
    },
    {
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 0, 0, 0, 0, 0, 0, 0}
    }
};

or

std::array<std::array<std::array<int, MAX_CELL>, MAX_ROW>, LEVELS_COUNT> LevelsArray =
{
    {
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 0, 0, 0, 0, 0, 0, 0}
    },
    {
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 0, 0, 0, 0, 0, 0, 0}
    }
};
Erbureth
  • 3,378
  • 22
  • 39
  • `int LevelsArray[LEVELS_COUNT][MAX_ROW][MAX_CELL] = { anArray1, anArray2};` wouldn't work, you've to give the array elements inside this array. – legends2k Feb 02 '15 at 07:59
  • the std::array example gives me :error C2078: too many initializers error – user63898 Feb 02 '15 at 12:13
  • vector example gives error: error C2552: 'LevelsArray' : non-aggregates cannot be initialized with initializer list in visual studio 2012 – user63898 Feb 02 '15 at 13:24
  • @user63898 You need proper C++11 support for initializer list and std:array, using C++03 would be more complicated. – Erbureth Feb 02 '15 at 14:09
0

You're missing specifying the other dimensions of the container which depends on the element contained. Try this

int LevelsArray[][MAX_ROW][MAX_CELL] =
{
    {
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 0, 0, 0, 0, 0, 0, 0}
    },
    {
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 1, 1, 0, 1, 1, 1, 0},
        { 0, 0, 0, 0, 0, 0, 0, 0}
    }
};

Having the elements (2D arrays) as separate arrays would mean that you cannot store those arrays inside another array; you may only store pointers to them. With this approach, you can refer the inner elements too convienetly with a reference like this

auto const &anArray1 = LevelsArray[0];

and use it elsewhere.

legends2k
  • 31,634
  • 25
  • 118
  • 222
  • is there any way to copy the array to int array not using c++11 and not looping all the Level array ? – user63898 Feb 02 '15 at 13:44
  • C++ as a language doesn't support initializing arrays with arrays. You've to copy them manually or use `std::copy` which too would do the same behind the scenes. If you really want flexible container like you ask, perhaps try `std::vector`. – legends2k Feb 02 '15 at 13:51
  • the vector make me problems also , see above commnets – user63898 Feb 02 '15 at 13:52
  • 1
    For that you need C++11 where `vector` gets a `std::initializer_list` taking constructor. I don't think VS 2012 has it. – legends2k Feb 02 '15 at 13:55