• 11
• 9
• 10
• 9
• 11

# std::vector question

This topic is 4212 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

If I create a two dimensional std::vector (4x4) like this: vector <vector<int> > LBlock(4, vector<int>(4)); Can I somehow initialize the elements in the vector like a normal array like this? I have to do this in order to get the order of the 0's and 1's the way I want it.
LBlock = {{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}};


Question #2 Can I allot a two dimensional vector to a two dimensional array somehow. If this works, I don't have to worry about initializing the vectors the way I mentioned above. Neither vecBlock = arrBlock; or type casting works, is there any other way?

##### Share on other sites
(1) Is there a reason you don't want to use the standard push_back function to initialise your vector?
  for( int firstIndex = 0; firstIndex < 4; firstIndex++ ){  for( int secondIndex = 0; secondIndex < 4; secondIndex++ )  {     (LBlock[firstIndex]).push_back( 0 );  }}

(2) Depending on the size of your arrays and vectors you could just loop through the elements.

Cheers
Amos

##### Share on other sites
[EDIT - Sorry Amos - you beat me to it [smile]]

I may be wrong, but I am pretty sure that the answer is no to both of those questions.

vector data is allocated on the heap, even when the vector itself is static, so if nothing else, that would preclude being able to initialise it with the syntax above.

And I am not aware of any implicit conversion from a 2D array to a vector of vectors. For a start, they have different properties - a 2D array is always rectangular but a vector of vectors is not.

It is fairly trivial to write such a converter though, so you could initialise a 2D array statically then, on start up, use a function to copy this into a vector of vectors.

int Data[3][3]={{ 0,1,0 },                { 1,0,1 },                { 0,1,0 }};std::vector<std::vector<int> > Vec;void Init(){    Vec.resize(3);    for(int Y=0;Y<3;++Y)        {        for(int X=0;X<3;++X)            {            Vec[Y].push_back(Data[Y][X])); // or is that Data[X][Y]? I can never remember            }        }}

I think that is right. I get a bit confused by 2D arrays and avoid them like the plague to be honest.

If your container is always going to be rectangluar, I understand that there is a boost::multidimensional_array (or something) that may be useful. Alternatively, here's a class I use for 2D game maps:

class Map{private:    std::vector<int> V; int W,H;public:    Map(int Width,int Height) : W(Width),H(Height) { V.resize(W*H); }    int &operator()(int X,int Y);    int operator()(int X,int Y) const;    int Width() const { return W; }    int Height() const { return H; }    class BoundsError{ };};int &Map::operator()(int X,int Y){    if(X<0 || X>=W || Y<0 || Y>=H) throw BoundsError();    return V[(Y*W)+X];}int Map::operator()(int X,int Y) const{    if(X<0 || X>=W || Y<0 || Y>=H) throw BoundsError();    return V[(Y*W)+X];}int main(){    Map map(10,10);    map(3,2)=23;    std::cout << map(9,4) << std::endl; // etc}

This approach maintains the invariant that your container is rectangular and it also guarantees that the data is contiguous in memory, which a vector of vectors does not.

HTH Paul

##### Share on other sites
Quote:
 Can I somehow initialize the elements in the vector like a normal array like this?

No, only normal arrays can be initialized thus, although there is discussion about extending C++ in this direction.

Quote:
 Can I allot a two dimensional vector to a two dimensional array somehow.

No. For starters you don't have a 2D vector, but a vector of vectors, each of which exists independently and not really as an integral part of a 2D structure. The fact that those vectors have been themselves put in a vector is completely incidental from their point of view.

There do exist true multidimensional array classes, like boost::multi_array. Also, depending on how exactly you plan on using the data, the std::valarray class may be what you are looking for.

##### Share on other sites
I didn't realize I could put the push_backs into a function like that. That's probably the easiest way I can make it. Something like this:

void SetPiece(int Data[]) {    Vec.resize(3); // not sure what this line does though, can only guess :)    for(int Y=0;Y<4;++Y) {        for(int X=0;X<4;++X) {            piece[Y].push_back(Data[Y][X]));        }    }}SetPiece(LBlock);

Probably have to change it to a vector with vector's though, since i've used that in the program so far. I hope they extend the language and makes this possible though, I find it really useful sometimes. Thank you all.

##### Share on other sites
Plus if you're going to be initialising your vector of vectors because you already know its dimensions do you really need a vector or would a 2D array suit your needs better?

Cheers
Amos

##### Share on other sites
Quote:
 Original post by passwordVec.resize(3); // not sure what this line does though, can only guess :)

Sets the size of the vector to 3. If there were originally fewer elements in the vector, the new elements are default-initialized. If there were more, the vector gets truncated.

Quote:
 Probably have to change it to a vector with vector's though, since i've used that in the program so far.

Incidentally, if you're only going to use the vector as a static array, you may be better off just using an array in the first place, or grab a STL array wrapper like boost::array or std::tr1::array (where available).

Quote:
 I hope they extend the language and makes this possible though, I find it really useful sometimes. Thank you all.

If you are curious, check out the current discussion. For more, go here and scroll down to or search for the papers about "Initializer lists".

[Edited by - Fruny on October 9, 2006 5:58:41 PM]

##### Share on other sites
Hey I dont got any live code but I can tell you somethin, im making a game that is using a PLETHORA of multidimentional[sic] vectors in it.
The way I make a normal vector behave like a multidimensional one is to create a width variable and use that to controll moving "up" and "down".
Heres the logic like so.

vector <int> board(9, 0);for (int i = 0;i < board.size(); i++)    display board;This gets displayed.000000000int boardWidth = 3;int j = 1;for (int i = 0;i < board.size(); i++){    display board;    j++;    if (j == boardWidth)       newline;}This gets displayed.000000000

if you wanted to move something up or down on the board, you simply add or subtract the width of the board.

if you want to use X and Y coordinates heres an little algorithm I made that will convert a vector location into X and Y coordinated, and another one that will take X and Y coordinated and convert them into a vector spot.

Here this takes a vector location and makes it into x and y coordinated.
int x = vector loacation + 1;int y = 0;while (x > boardWidth){        x -= boardWidth;	y++;}

This will take X and Y coordinates and return a vector location.
int XY(int x, int y, boardWidth){	x--;	y--;		while (y > 0)		{			y--;			x += boardWidth;		}	return x;}

so you could do...
board[XY(1,1,3)] = 1;orboard[5] = 1;

both are the same thing.

Hope I was of some assistance.

int XYtoIndex(int X,int Y,int Width){    return (Y*Width)+X;}void IndextoXY(int Index,int Width,int &X,int &Y){    X=Index%Width;    Y=Index/Width;}