首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向量的emplace_back()与push_back()

向量的emplace_back()与push_back()
EN

Stack Overflow用户
提问于 2021-08-08 07:27:09
回答 1查看 308关注 0票数 1

我知道这个问题被问了很多,我看过很多引用"emplace_back构造就地,push_back()构造和复制“的解释。一些帖子询问为什么emplace_back调用复制构造函数,因为它们没有为向量保留内存。

但是对于下面的例子,我不知道emplace_back()比push_back()实现的更多。有人回答说“你需要为emplace_back()实现一个移动构造函数才能工作”,但是push_back()也可以利用这个移动构造函数。那么有什么不同呢?

代码语言:javascript
复制
#include <iostream>
#include <vector>
using namespace std;
 

class Int{
    public:
    int* p;
    Int(int x): p(new int(x)) {cout<<"constructor called for "<<*p<<endl;}
    Int(const Int& x): p(new int(*(x.p))) {cout<<"copy constructor called for "<<*p<<endl;}
    ~Int(){
        if (p!= nullptr) {cout<<"destructor called for "<<*p<<endl;}
        else{cout<<"destructor called for null ptr"<<endl;}   
        delete p; 
    }
    
    Int(Int&& x): p(x.p) {
        x.p = nullptr; 
        cout<<"move constructor called for "<<*p<<endl;  // move constructor, remove to test emplace_back()
        }
};

int main(){
    vector<Int> v;
    v.reserve(1);
    v.emplace_back(Int(1));  // can switch to push_back()
    // v.push_back(Int(1));
    cout<<"end program"<<endl;
}

对我来说,这两种方法似乎都调用复制构造函数而不调用移动构造函数,如果有移动构造函数,则调用移动构造函数。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-08 07:31:56

emplace_back通过将参数转发到元素类型的构造函数来就地构造元素,因此您可以

代码语言:javascript
复制
v.emplace_back(1); // forwarding 1 to Int::Int(int) to construct the element directly

push_back总是需要一个元素,即一个Int。当您将1作为v.push_back(1);传递给它时,会发生隐式转换。(Int::Int(int)1构造一个临时Int,然后将其传递给push_back,随后Int的move构造函数从临时构造元素构造该元素。即比v.emplace_back(1);多一次移动构造函数调用。

您还可以将Int传递给像v.emplace_back(Int(1));这样的emplace_back,如上所述,临时Int被转发到Int的move构造函数来构造元素,该构造函数的作用与v.push_back(Int(1));相同。

正如@JeJo所建议的,emplace_backpush_back之间有另一个区别,因为C++17。emplace_back返回对插入元素的引用,而push_back不返回任何内容。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68698641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档