Nested class vector index access

Is it possible to pass the vector index '4' to the Height() function without passing it as a parameter of the function.

Basically, I'm trying to eliminate using 4 twice... what I'd LIKE the statement below to look like is this:
gx.Cell[4].Height();

The only way I can figure out how to get it to work is like this...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class grid{
  public:
	class CELL{
	  public:
	    int Height(int index); //returns the height of this cell
	 };
  
  std::vector<CELL> Cell;

};



int main()
{
  grid gx;
  /* Initialize Cell[size] */
  gx.Cell[4].Height(4);
	

}
Last edited on
Why do you need parameter at all? Can't you save everything you need to show height of this cell inside this celll?
Note that in your code, gx.Cell[4] does not exist, as the Cell vector in your gx variable is empty.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>

struct Cell
{
    Cell(int height) : _height(height) {}
    int height() const {return _height;}

private:
    int _height;
};

int main()
{
    std::vector<Cell> v = { 2, 4, 8, 16, 32 };

    for (std::size_t index = 0; index < v.size(); ++index)
        std::cout << "Height at index " << index << " is " << v[index].height() << '\n';
}


http://ideone.com/g5La9I
Neither of you are addressing my question at all.

I'm trying to keep the code simple to better explain the problem. I know the example doesn't show the Cell vector initialized. But that's not my issue, I know how to do that.

I also know Height() doesn't need a parameter. However, there are other functions I plan to implement, such as CellCenter() which will return a 'point' that's equal to the center of the grid cell. To do this, I need to know that I'm on cell 4, or whatever.

I'm just trying to figure out how to pass a vector index to a function such as in the example above. I'm almost to the point of assuming it's beyond the scope of C++.
Last edited on
To do this, I need to know that I'm on cell 4
1
2
3
4
5
6
7
CELL::CELL(int index, /*...*/) //CELL object will know its own index
//...
grid::grid() //default constructor
{
    for(int i = 0; i < CELL_COUNT; ++i)
        Cell.emplace_back( i + 1, /*...*/); //Assuming Cells are counted from 1
}
I wrote in my suggestion: store cell number in CELL itself. Another way is to make operator[] of grid return wrapper.
Like:
1
2
3
4
5
6
7
8
9
10
11
12
13
class cell_wrapper
{
    CELL& value;
    int index;
    
    cell_wrapper(int ind, CELL& v) : value(v), index(ind) {};
    //Some functions working with both CELL and index or passing calls to CELL.
}

cell_wrapper grid::operator[](int index)
{
    return cell_wrapper(index, Cell[index]) //Returning Index aware CELL adapter
}


And last: if some methods does not have sense for CELL object without encompassing grid, it should not be member of CELL.
as CellCenter() which will return a 'point' that's equal to the center of the grid cell.
How should that function work if you create standalone CELL object? If your answer "it shouldn't" then it shouldn't be CELL member.
Last edited on
So are you trying to say that you need to pass a value to the cell that is the same as it's position in the grid? The easiest way would simply to give the Cell its position in the grid upon construction. If Cell's move around, then you can probably add a set function to change it, but otherwise its fine. So in your example:
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
class grid {
    public:
        class Cell {
            public:
                Cell() : _pos(std::size_t pos) : _pos(pos) {}
                int Height();

            private:
                std::size_t _pos;
        };

        grid() : cells() {
            // insert cells
            for (std::size_t i = 0; i < 1000; ++i)
                cells.emplace_back(i);
        }

        // you could probably also wrap this and do it directly
        Cell& operator[] (std::size_t pos) { return cells[pos]; }
        const Cell& operator[] (std::size_t pos) const { return cells[pos]; }

    private:
        std::vector<Cell> cells;
};

int main() {
    grid gx;
    // ...

    gx[4].Height();
    // ...
}


EDIT:
Ninja'd by @MiiNiPaa
Last edited on
Thanks to both of you for being so helpful. It's my fault for not explaining my problem more clearly the first time, so let me start again with a bit more detail.

For a visual of the 'grid' where each number represents the 'index' of a single cell, think of a Checkers board or any tile-based game. I'm building this for game programming utilizing Allegro 5 for my graphics library.

The 'point' class below is defined elsewhere, but simply explained it just contains an X and Y integer value that represents a pixel position.

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
class grid{
public:
	class cell{
	  point UpperLeftCorner()
	  {
	      //Would calculate the upper point position of this cell.
	      //To do so, need to know which cell index we are working with.
	      //Would like to figure out how to extract Cell vector index,
	      //without having to pass a parameter thru UpperLeftCorner().
	   }
	 };

	std::vector<cell> Cell;

	void Create(int rows, int columns, int cellsWidth, int cellsHeight)
	{
		//Error check here
		gRows = rows;
		gColumns = columns;
		cWidth = cellsWidth;
		cHeight = cellsHeight;
		
		cell tmpCell;
		for (int i=0; i<(rows*columns); ++i)
			Cell.push_back(tmpCell);

		//First cell of the grid would be index = 0; last cell would be Cell.size()-1
	}

	//Returns grid Height / Width
	int Height() { return (gRows*cHeight); }
	int Width() { return (gColumns*cWidth); }
	
	int CellCount() { return (gRows*gColumns); }
private:
	int gRows;
	int gColumns;
	int cWidth;
	int cHeight;

};


So for example, if I were to implement this....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    grid g;
    //Creates a grid with dimensions 5x5 cells (25 cells total indexed 0 thru 24)
    //Each cell is 32 pixels width by 32 pixels height
    g.Create(5,5,32,32);
   
    //Get the upper left pixel position of the 4th (for example) cell
   point thisCell = g.Cell[3].UpperLeftCorner();

    //I could later use 'thisCell' to draw a graphic or track a sprite's movement
    // thisCell.X = upper left X value of 4th cell indexed 3
    //thisCell.Y = upper left Y value of 4th cell indexed 3

}


So in summary, my questions revolves around how do I 'pass' the literal '3' from this statement in the main() function without having to add a parameter to the UpperLeftCorner() function?
point thisCell = g.Cell[3].UpperLeftCorner();
1
2
3
4
//Would calculate the upper point position of this cell.
//To do so, need to know which cell index we are working with.
//Would like to figure out how to extract Cell vector index,
//without having to pass a parameter thru UpperLeftCorner(). 
If class needs to know something about other class to do some operation then this operation is not his responsibility.

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
class grid
{
    point UpperLeftCorner(int index)
    {
        //Calculate UL corner depending on board size etc...
    }
}
//...
g.UpperLeftCorner(3);

//or

class grid
{
    class CellWrapper
    {
        int index;
        CELL& target;
        grid& owner;
        point UpperLeftCorner()
        {
            point UL = owner.Height() / owner.gRows * index %//... etc
        }
        operator CELL() { return target; } //Conversion
    };
    operator[](int index)
    {
        return CellWrapper(index, Cell[index], *this) //Returning Index aware CELL adapter
    }
};
//...
point thisCell = g.Cell[3].UpperLeftCorner(); //Almost like in your code 

Last edited on
Thanks! I got it to work. :)
Topic archived. No new replies allowed.