C++ emplace_back与push_back的区别

https://blog.csdn.net/p942005405/article/details/84764104

1.例子

上面链接中给出的例子:

#include <vector>  
#include <string>  
#include <iostream>  
 
struct President  
{  
    std::string name;  
    std::string country;  
    int year;  
 
    President(std::string p_name, std::string p_country, int p_year)  
        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)  
    {  
        std::cout << "I am being constructed.
";  
    }
    President(const President& other)
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being copy constructed.
";
    }
    President(President&& other)  
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)  
    {  
        std::cout << "I am being moved.
";  
    }  
    President& operator=(const President& other);  
};  
 
int main()  
{  
    std::vector<President> elections;  
    std::cout << "emplace_back:
";  
    elections.emplace_back("Nelson Mandela", "South Africa", 1994); //没有类的创建  
 
    std::vector<President> reElections;  
    std::cout << "
push_back:
";  
    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));  
     std::cout << "emplace_back:
";//我添加的
    reElections.emplace_back(President("Franklin Delano Roosevelt", "the USA", 1936));

    std::cout << "
Contents:
";  
    for (President const& president: elections) {  
       std::cout << president.name << " was elected president of "  
            << president.country << " in " << president.year << ".
";  
    }  
    for (President const& president: reElections) {  
        std::cout << president.name << " was re-elected president of "  
            << president.country << " in " << president.year << ".
";  
    }
 
}

输出结果:

emplace_back:
I am being constructed.

push_back:
I am being constructed.
I am being moved.
emplace_back:
I am being constructed.
I am being moved.
I am being copy constructed.

Contents:
Nelson Mandela was elected president of South Africa in 1994.
Franklin Delano Roosevelt was re-elected president of the USA in 1936.
Franklin Delano Roosevelt was re-elected president of the USA in 1936.

第二个emplace_back的地方好奇怪,所以说emplace_back不是直接调用&&移动构造函数的,为什么还会多了一次拷贝?(g++版本)

又尝试:

    std::cout << "push_back:
";
    elections.push_back("Nelson Mandela", "South Africa", 1994);

报错:

error: no matching function for call to 'std::vector<President>::push_back(const char [15], const char [13], int)'

因为push_back只能接受一个参数。

2.区别

在插入参数时,push_back需要构建临时对象+拷贝+销毁,而emplace只需要直接拷贝即可。

在插入临时对象时,两者没有区别,都要三步走,创建+move(如果有move的话,没有就是拷贝构造)+销毁。

插入对象实例,两者没有区别。

以上总结自https://zhuanlan.zhihu.com/p/183861524,博文中举的例子简单实用易见!

上面这张图也非常形象。

原文地址:https://www.cnblogs.com/BlueBlueSea/p/13885986.html