为循环内创建的对象调用哪个C ++向量push_back

时间:2017-01-19 02:21:59

标签: c++ vector overloading lvalue rvalue

这是一个非常基本的问题,但我似乎无法理解这里发生的事情的逻辑。请考虑代码段:

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
            }

        }
    }

此代码工作正常,即退出构造函数后,向量(向量)allCells中的所有对象仍存储适当的信息。我的问题是这是如何实现的?根据定义,vector.push_back只有两个变体:

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

它不能调用第二个变体,因为临时aCell对象是左值对象。如果它调用第一个变量,则它会推送临时对象aCell,该对象在循环终止时被销毁。

对此内容的任何解释都表示赞赏。

编辑:由于Sam Varshavchik和songyuanyao指出的错误修复了代码

1 个答案:

答案 0 :(得分:2)

  

如果它调用第一个变量,则它会推送临时对象aCell,当循环终止时它会被销毁。

是的,因为aCell是一个左值,所以会调用第一个版本。这很好,因为push_back ed元素是从参数初始化的副本;它独立于局部变量aCell

  

将给定的元素值追加到容器的末尾。

     

1)新元素初始化为值的副本。

BTW:在for循环中使用allCells[i]时,您的代码具有未定义的行为,因为此时allCells仍为空,它没有元素。注意reserve不会更改vector的大小,但会改变resize的容量。

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
        }
    }
}