The difference between push_back and emplace_back in vector

1. The difference between the two

Before introducing a right-value reference, a transfer constructor, and a transfer replication operator, a right-value element (temporary object) is usually added to the container by push_back(), the constructor is first called to construct the temporary object, and then the copy constructor is called to place the temporary object in the container. The original temporary variable is released. The problem is that the resources for temporary variable applications are wasted.  
After introducing the right-value reference, the push_back() right-value will call the constructor and the transfer constructor. There is room for further optimization by adding an element at the end of the container using emplace_back, which is in-situ constructed without triggering copy and transfer constructs. Moreover, the invocation form is more concise, and the members of the temporary object are initialized directly according to the parameters.  

2. Code examples

#include <vector>  
#include <string>  
#include <iostream>  

struct President  
{  
    std::string name;  
    std::string country;  
    int year;  
    
    //Constructor
    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.\n";  
    }
    
    //copy constructor
    President(const President& other)
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being copy constructed.\n";
    }

    //Move Constructor
    President(President&& other)  
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)  
    {  
        std::cout << "I am being moved.\n";  
    }

    //Assignment operator function  
    President& operator=(const President& other);  
};  

int main()  
{  
    std::vector<President> elections;  
    std::cout << "emplace_back:\n";  
    elections.emplace_back("Nelson Mandela", "South Africa", 1994); //No class creation  

    std::vector<President> reElections;  
    std::cout << "\npush_back:\n";  
    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));  

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

}

Output:

emplace_back:
I am being constructed.

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

Contents:
Nelson Mandela was elected president of South Africa in 1994.

Reference resources: https://blog.csdn.net/xiaolewennofollow/article/details/52559364

Posted by flaab on Sat, 23 Mar 2019 12:00:53 -0700