C++ vector中push_back()和emplace_back()的区别
vector的emplace_back()函数是C++11后增加的函数,我们看一看这两个函数的解释:
1.
adds an element to the end (public member function) |
(C++11) |
constructs an element in-place at the end (public member function) |
从上面的解释来看好像是不太好理解,我们看两个函数的具体实现:
std::vector<T,Allocator>::push_back
void push_back( const T& value ); |
constexpr void push_back( const T& value ); |
void push_back( T&& value ); |
constexpr void push_back( T&& value ); |
std::vector<T,Allocator>::emplace_back
template< class... Args > |
template< class... Args > |
template< class... Args > |
从上面可以看到,push_back()函数的参数是容器对象的左值或者右值,所以只能是已经包装的好的对象才能够当作参数。而对于emplace_back()则是可以传如对象所有需要的参数,然后系统回先根据参数生成一个临时对象,然后将生成的临时对象move到vector中。因此有如下的写法就会出错:
class Person
{
public:
std::string name_;
int age_;
Person(std::string name, int age): name_(name), age_(age) {}
Person(Person&& rhs) {
name_ = std::move(rhs.name_);
age_ = rhs.age_;
std::cout << "move" << std::endl;
}
~Person() {}
};
int main() {
std::vector<Person> ps;
ps.push_back("aaaaa", 10); // error
ps.push_back("bbbbb", 10); // error
ps.push_back("ccccc", 10); // error
ps.emplace_back("aaaaa", 10); // right
ps.emplace_back("bbbbb", 10); // right
ps.emplace_back("ccccc", 10); // right
}
特别的如果对象的构建参数只有一个,并且没有explict修饰,那么表现出push_back()和emplace_back()看起来一样的用法,但是对于push_back(parm)来说,他是先生成一个临时变量Object(pram)然后将将这个临时变量copy/move给vector.而对于empalce_back就直接生成一个变量直接到vector,参见[1].
当两个函数都是对象参数的时候, emplace_back(obj) 直接将obj copy/move到一个vector尾端的对象中。而push_back(obj)则是将obj copy/move一个临时对象,这临时对象在move到vector尾部。如下:
#include <iostream>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class Person
{
public:
std::string name_;
int age_;
Person(std::string name, int age): name_(name), age_(age) {}
Person(Person&& rhs) {
name_ = std::move(rhs.name_);
age_ = rhs.age_;
std::cout << "move" << std::endl;
}
~Person() {}
};
int main() {
std::vector<Person> ps;
Person a("aaaaa", 1);
Person b("bbbbb", 2);
Person c("ccccc", 3);
ps.emplace_back(std::move(a));
std::cout<<"========" << std::endl;
ps.push_back(std::move(b));
std::vector<Person> psc;
std::cout << "---------" << std::endl;
for(Person &p: ps) {
std::cout<< p.name_ << std::endl;
}
for(Person& p: ps) {
psc.push_back(std::move(p));
}
for(Person &p: ps) {
std::cout<< p.age_ << std::endl;
}
return 0;
}
打印结果如下:
move
========
move
move
---------
aaaaa
bbbbb
move
move
move
1
2
[1]
c++11 之emplace_back 与 push_back的区别_学之知之的博客-CSDN博客_emplace_backzxu
推荐阅读
-
小计C++中的引用和vector
-
在C++中,函数名前的const和函数名后的const的区别详解
-
C++中重载、覆盖和隐藏的区别,以及适用场景
-
C++中static_cast/const_cast/dynamic_cast/reinterpret_cast的区别和使用
-
面试知识点总结——C++中公有继承、私有继承和保护继承的区别
-
C/C++编程笔记:数据类型中 float 和 double 的区别!细节讲解
-
C++ 中emplace_back和push_back差异
-
opencv-python与c++ opencv中的一些区别和基础的知识
-
C语言中的const和C++中的const区别及使用介绍
-
C++中struct和class的区别介绍