概述
在C++11中,在引入右值的升级后,调用push_back变的更为高效,原本需要调用构造函数构造这个临时对象,然后调用拷贝构造函数将这个临时对象放入容器中。在C++11升级后,只需要调用构造函数,然后调用移动拷贝函数。
就好比,现在手里有个面包,要把这个放到面包袋子里,原来的逻辑是,生产一个面包,然后在面包袋子里根据生产的面包再复制一个一摸一样的,在引入右值引用升级之后,现在的push_back的逻辑是,生产一个面包,然后把这个面包挪到袋子里(也就是移动拷贝)而不是再照着这个面包复制一个新的。
在此基础上,可以更快些吗?答案是可以的,在C++11中,可以调用emplace_back,emplace_back直接通过参数构造对象至容器中,不需要拷贝或者移动。如果继续使用面包的例子(这里可能不太恰当了),就好比面包生产出来就直接在袋子里了,没有拷贝,没有移动。如此会更加高效。
这是标准库vector的emplace_back方法的介绍以及一些例子:
std::vector<T,Allocator>::emplace_back - cppreference.com
使用
//以下代表功能一样,但效率不一样
vector
emplace <--> insert
emplace_back <--> push_back
set
emplcace <--> insert
map
emplace <--> insert
简单的使用,以vector的emplace_back为例
#include <iostream>
#include <vector>
using namespace std;
struct Student {
string name;
int age;
Student(string&& n, int a)
:name(std::move(n)), age(a)
{
cout << "构造" << endl;
}
Student(const Student& s)
: name(std::move(s.name)), age(s.age)
{
cout << "拷贝构造" << endl;;
}
Student(Student&& s)
:name(std::move(s.name)), age(s.age)
{
cout << "移动构造" << endl;
}
Student& operator=(const Student& s);
};
int main()
{
vector<Student> classes_one;
vector<Student> classes_two;
cout << "emplace_back:" << endl;
classes_one.emplace_back("xiaohong", 24);
cout << "push_back:" << endl;
classes_two.push_back(Student("xiaoming", 23));
}
执行结果

原理
push_back():先向容器尾部添加一个右值元素(临时对象),然后调用构造函数构造出这个临时对象,最后调用移动构造函数将这个临时对象放入容器中并释放这个临时对象。
注:

本文探讨了C++11中push_back和emplace_back在向vector添加元素时的效率差异,前者通过构造函数和移动构造,后者原地构造。通过面包和面包袋的比喻,展示了emplace_back的高效优势。

657

被折叠的 条评论
为什么被折叠?



