在C++中,std::vector
提供了 push_back
和 emplace_back
两种方法来向向量的末尾添加元素。这两者的主要区别在于它们如何处理元素的构造过程。下面详细介绍它们的区别和使用场景。
1. push_back
- 功能:
push_back
将一个已构造好的对象添加到向量的末尾。 - 步骤:
- 首先构造一个临时对象。
- 然后将这个临时对象拷贝或移动到向量的末尾。
- 适用场景:当你已经有一个现成的对象,或者对象的构造过程比较复杂时,使用
push_back
更为方便。
2. emplace_back
- 功能:
emplace_back
直接在向量的末尾构造一个新对象,避免了临时对象的创建和拷贝/移动操作。 - 步骤:
- 直接在向量的末尾位置调用对象的构造函数,传入所需的参数。
- 适用场景:当你知道对象的构造参数,并且希望直接在目标位置构造对象以提高性能时,使用
emplace_back
更为高效。
代码示例
使用 push_back
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> vec;
std::string temp = "Hello";
vec.push_back(temp); // 先构造 temp,再拷贝到 vec 末尾
vec.push_back("World"); // 先构造临时对象,再拷贝到 vec 末尾
for (const auto& str : vec) {
std::cout << str << " ";
}
std::cout << std::endl;
return 0;
}
使用 emplace_back
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> vec;
vec.emplace_back("Hello"); // 直接在 vec 末尾构造 "Hello"
vec.emplace_back("World"); // 直接在 vec 末尾构造 "World"
for (const auto& str : vec) {
std::cout << str << " ";
}
std::cout << std::endl;
return 0;
}
性能差异
push_back
:涉及临时对象的创建和拷贝/移动操作,可能会有额外的开销。emplace_back
:直接在目标位置构造对象,避免了临时对象的创建和拷贝/移动操作,通常更高效。
适用场景
push_back
:适用于已经有一个现成的对象,或者对象的构造过程比较复杂的情况。emplace_back
:适用于知道对象的构造参数,并且希望直接在目标位置构造对象以提高性能的情况。
总结
push_back
:先构造临时对象,再拷贝/移动到向量末尾。emplace_back
:直接在向量末尾构造对象,避免临时对象的创建和拷贝/移动操作。
选择哪种方法取决于具体的需求和场景。如果性能是关键因素,且对象的构造参数已知,建议使用 emplace_back
。否则,push_back
也是一种简单且有效的方法。