C++之emplace_back() VS push_back()
最近在提交的时候发现同样的代码别人比我的快,原因就是我代码中的push_back()而别人用的是emplace_back().
于是我上cppreference.com了解了一下emplace_back()。
使用push_back()的时候,会首先构造一个元素,然后拷贝复制传递给容器。使用emplace_back()时,会在容器所在的内存空间直接构造一个元素,避免了额外的移动或赋值操作。通过下面的例子可以看出:
#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.\n";
}
President(President&& other)
: name(std::move(other.name)), country(std::move(other.country)), year(other.year)
{
std::cout << "I am being moved.\n";
}
President& operator=(const President& other) = default;
};
int main()
{
std::vector<President> elections;
std::cout << "emplace_back:\n";
elections.emplace_back("Nelson Mandela", "South Africa", 1994);
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.
Franklin Delano Roosevelt was re-elected president of the USA in 1936.
push_back()调用了复制函数,而emplace_back()没有,显然优先选择emplace_back().
最后附上一个写的非常清楚的博客(我就直接复制了)。http://blog.csdn.net/zhouguoqionghai/article/details/47414551。
C++11的STL中新增加了emplace() 函数和 emplace_back() 函数,用来实现insert() 函数和 push_back() 函数的功能。
如果容器中的元素是对象:
emplace() 函数的功能是可以直接将参数传给对象的构造函数,在容器中构造出一个对象,从而实现 0 拷贝。(底层机制是调用placement new即布局new运算符来实现的)。
假设类MyClass 有构造函数 MyClass(T1 val1,T2 val2);
那么container.emplace(container.end() ,val1, val2) 可以直接在容器的末尾构造出一个对象,如果用container.insert(container.end() ,MyClass(val1,val2)) 会先构造一个对象,然后拷贝到容器的末尾。
同样的,emplace_back() 和 push_back() 的差别类似。
如果是一个已有的对象 MyClass obj;container.emplace(…, obj) 和 container.emplace_back(obj)的效率差不多。
上一篇: xhtml和html5的区别是什么
下一篇: matplotlib画图时调整子图的间距
推荐阅读
-
C++ 中emplace_back和push_back差异
-
《Unreal Engine 4 Scriptingwith C++ Cookbook》翻译 之 第一章 UE4开发工具 3. 在VS中创建第一个C++工程
-
c/c++ 标准顺序容器 之 push_back,push_front,insert,emplace 操作
-
[C++] push_back vs emplace_back
-
C++ std::vector 的 emplace_back 能否完全取代 push_back
-
c++11中emplace_back vs push_back
-
C++11 之 emplace_back() 与 push_back() 的区别
-
c++11 之emplace_back 与 push_back的区别
-
c++ push_back与emplace_back
-
C++之emplace_back() VS push_back()