Initializing a 2d object array with its array position

I'm creating a sort of cellular automaton and I'm looking for a convenient way to initialise a 2d array of objects with their positions.

I have a cell which needs to be aware of its own position in a (let's say) 20 x 20 grid and as every cell needs to have a position, I've currently got the position passed as two integers to the constructor;

1
2
3
4
5
6
7
8
9
10
11
12
class cell
{
	int cell_x_pos;
	int cell_y_pos;
Public:
	cell (int x_pos, int y_pos)
	{
		cell_x_pos = x_pos;
		cell_y_pos = y_pos;
	}

}


I have a grid class and I'd like this grid class to create and initialize 20x20 cells in a 2d array. Is there any way in C++ to declare an array of objects and pass the object's position in the array as a parameter to the constructor?




I guess I'd like something like the following declaration (which is obviously incorrect syntax for C++):
 
	cell grid_array[n=20][m=20](n,m);


Otherwise, I'm going to have to remove it from the constructor and create and iteratively call a SetPosition function for each cell.

Is there any way to do this in one fell swoop?

You can do something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

constexpr int Size = 20;

class Cell {
    static int irow, icol;  // automatically start at 0
    int row, col;
public:
    Cell() {
        row = irow;
        col = icol;
        if (++icol == Size) {
            icol = 0;
            ++irow;
        }
    }
    void print() {
        std::cout << row << ", " << col << '\n';
    }
};

int Cell::irow, Cell::icol; // instantiating statics

int main() {
    Cell g[Size][Size];
    for (int row = 0; row < Size; row++) {
        for (int col = 0; col < Size; col++)
            g[row][col].print();
        std::cout << '\n';
    }
    return 0;
}

Last edited on
Not sure if you can avoid explicitly writing out the loops. There are tricks like fill, but that's if you want the same value throughout the matrix, or iota on a range, but then you'd probably be doing two passes (first default values, then increments).

Maybe someone knows a neater way to rewrite the loop in my Grid constructor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <vector>
using namespace std;

struct Cell
{
    Cell(int x, int y)
    {
        this->x = x;
        this->y = y;
    }
    int x;
    int y;
};
typedef Cell Cell;

ostream& operator<<(ostream& os, const Cell& c) 
{
    os << "(" << c.x << ", " << c.y << ")";
    return os;
}

class Grid
{
public:
    Grid(int rows, int cols)
    {
        grid_.reserve(rows);
        for(int r=0; r<rows; ++r)
        {
            vector<Cell> row;
            row.reserve(cols);
            for (int c=0; c<cols; ++c)
                row.emplace_back(r,c);
            grid_.emplace_back(row);
        }
    }
    vector<Cell>& operator[](int i)
    {
        return grid_[i];
    }
    void show()
    {
        for(auto& row : grid_)
        {
            for(auto& c : row)
                cout << c << " ";
            cout << endl;
        }
    }
    
private:
    vector<vector<Cell>> grid_;
};

int main() 
{
    Grid g(5,10);
    g.show();
    cout << endl;
    g[2][7] = Cell(9999,8888);
    g.show();
}


Can run at https://repl.it/repls/OddWiryInvocation


(0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) 
(1, 0) (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8) (1, 9) 
(2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) (2, 9) 
(3, 0) (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8) (3, 9) 
(4, 0) (4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8) (4, 9) 

(0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) 
(1, 0) (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8) (1, 9) 
(2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (9999, 8888) (2, 8) (2, 9) 
(3, 0) (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8) (3, 9) 
(4, 0) (4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8) (4, 9) 

Last edited on
Not sure if you can avoid explicitly writing out the loops.


It's looking that way! Thanks for your input people. I'm happy doing it the long way so long as I'm not missing an obvious shortcut.
Topic archived. No new replies allowed.