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

Ben*_*tch 9 c++ stdvector c++11

所以我试图在我的矢量背面添加整数,并错误地认为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;
}
Run Code Online (Sandbox Code Playgroud)

回报是:

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
Run Code Online (Sandbox Code Playgroud)

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

Sha*_*our 9

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

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

这对于重物来说很重要.我们可以看到这是原始提案的动机,其中说:

放置插入的动机是容器 - 尤其是基于节点的容器 - 对于重物的存储非常有用.在某些环境中,效率非常重要,但通常无法在不复制元素的情况下将元素放入容器中.重物可以直接存储其数据,在这种情况下,移动语义不会提高复制性能.此外,当效率至关重要时,解决方案不能依赖于编译器优化,因为它们是可选的,并且可能不会出现在最需要它们的地方.放置插入让我们在我们想要的容器中创建一次元素,而不必移动它或复制它.

我们可以举一个例子,这与Effective Modern C++ 有所不同第42项:考虑进驻而不是插入,其中有以下示例:

std::vector<std::string> vs; // container of std::string
vs.push_back("xyzzy"); // add string literal
Run Code Online (Sandbox Code Playgroud)

这导致创建临时而不是:

vs.emplace_back("xyzzy");
Run Code Online (Sandbox Code Playgroud)

没有.

  • 或许应该提到(因为OP问这个),在我们已经有一个我们想要复制/移动到向量中的现有对象的情况下,`push_back`和`emplace_back`完全相同; 只有当我们同时构建和推动时,它们才会有所不同,就像你的例子一样. (4认同)