vector.emplace_back()和vector.push_back()做同样的事情吗?

时间:2015-01-29 19:14:56

标签: c++ c++11 stdvector

所以我试图在我的矢量背面添加整数,并错误地认为push_back()将新数据添加到矢量的前面(又名矢量[0])。我在Xcode中进行了测试,并针对push_back()测试emplace_back()并获得了相同的结果。我认为他们是不同的,但这让我觉得他们可能会做同样的事情。如果是这样,为什么矢量有不同的方法?

这是我的代码以防万一:

#include <vector>
#include <iostream> 

using namespace std ;

int main(int argc, const char * argv[])
{
    // for push_back
    vector<int> push;
    push.push_back(1);
    push.push_back(2);
    push.push_back(3);
    push.push_back(4);
    push.push_back(5);
    push.push_back(6);
    //display push_back
    for (int i = 0; i < push.size(); i++) {
        cout << "push[" << i  << "]: " << push[i] << endl;
    }
    // distance between the two funcitons
    cout << endl << endl;

    vector<int> emplace;
    emplace.emplace_back(1);
    emplace.emplace_back(2);
    emplace.emplace_back(3);
    emplace.emplace_back(4);
    emplace.emplace_back(5);
    emplace.emplace_back(6);

    //display emplace_back
    for (int i = 0; i < emplace.size(); i++) {
        cout << "emplace[" << i  << "]: " << emplace[i] << endl;
    }
        return 0;
}

回报是:

push[0]: 1
push[1]: 2
push[2]: 3
push[3]: 4
push[4]: 5
push[5]: 6


emplace[0]: 1
emplace[1]: 2
emplace[2]: 3
emplace[3]: 4
emplace[4]: 5
emplace[5]: 6

我知道这是一个非常简单的问题,但我只是想确保我没有做出一些愚蠢的错误并且误解了矢量类的能力。

1 个答案:

答案 0 :(得分:9)

区别在于emplace_back将构建对象而不是复制或移动,cppreference section on std::vector::emplace_back说:

  

通常使用placement-new在容器提供的位置就地构造元素。参数args ...被转发到构造函数

这对于重物来说很重要。我们可以看到这是来自original proposal的动机,其中说:

  

展示位置插入的动机是容器 - 尤其是容器   基于节点的容器 - 对于重型存储非常有用   对象。在某些环境中,效率非常重要,但是   通常没有办法将元素放入容器中   复制它们。重物可以直接存储其数据,其中   案例移动语义不会提高复制性能。此外,   当效率至关重要时,解决方案不能依赖于编译器   优化,因为它们是可选的,可能不会发生在哪里   他们是最需要的。放置插入让我们创建一个元素   曾经,在我们想要的容器中,永远不必移动   它或复制它。它通过介绍以简单直接的方式实现   新的可变参数函数,它接受传递给的参数   元素的构造函数使用可变参数模板和完美转发。

我们可以举例说明这与Effective Modern C++ 有何不同第42项:考虑安置而不是插入,其中有以下示例:

std::vector<std::string> vs; // container of std::string
vs.push_back("xyzzy"); // add string literal

导致创建临时而不是:

vs.emplace_back("xyzzy");

没有。