Search code examples
c++vectoroverloadinglvaluervalue

Which C++ vector push_back is called for objects created inside a loop


This is a very basic question, but I cannot seem to get my head around the logic of what is going on here. Consider the code snippet:

class Board{
private:
    vector< vector<Cell> > allCells;
    int bheight;
    int bwidth;
public:
    Board(int width = 10, int height = 10){
        bheight = height; bwidth = width;
        allCells.resize(width);
        #loop for creating cell objects
        for(int i = 0; i < width; i++){
            allCells[i].reserve(height);
            for(int j = 0; j < height; j++){
                Cell aCell(i,j,0); #an object created inside a loop
                allCells[i].push_back(aCell); #push it into a vector
            }

        }
    }

This code works fine i.e. after exiting the constructor, all the objects in the vector (of vectors) allCells still stores appropriate information. My question is how was this achieved? By definition, vector.push_back has only two variants:

void push_back (const value_type& val);
void push_back (value_type&& val);

It cannot call the second variant since the temporary aCell object is a lvalue object. If it calls the first variant, then it push the temporary object aCell, which is destroyed when the loop terminates.

Any explanation of what goes on under the hood of this is appreciated.

EDIT: code fixed due to error pointed out by Sam Varshavchik and songyuanyao


Solution

  • If it calls the first variant, then it push the temporary object aCell, which is destroyed when the loop terminates.

    Yes the 1st version is called since aCell is an lvalue. It's fine because the push_backed element is copy initialized from the argument; it's independent of the local variable aCell.

    Appends the given element value to the end of the container.

    1) The new element is initialized as a copy of value.

    BTW: Your code has undefined behavior when allCells[i] is used in the for loop, because allCells is still empty at that time, it has no elements. Note reserve won't change the size but the capacity of the vector, but resize does.

    Board(int width = 10, int height = 10){
        bheight = height; bwidth = width;
        allCells.reserve(width);           // it should be allCells.resize(width) !!
        #loop for creating cell objects
        for(int i = 0; i < width; i++){
            allCells[i].reserve(height);
            for(int j = 0; j < height; j++){
                Cell aCell(i,j,0); #an object created inside a loop
                allCells[i].push_back(aCell); #push it into a vector
            }
        }
    }