emplace_back 和 push_back 是 C++ 容器(比如 std::vector、std::list 等)里常用的两个插入函数。
它们功能相似,但有本质区别 —— 是否需要“临时对象 + 拷贝/移动”。
下面我们详细对比👇
🧩 一、基本区别
| 对比项 | push_back | emplace_back |
|---|---|---|
| 语义 | “把一个现成的对象放进去” | “在容器内部原地构造一个对象” |
| 参数 | 必须是一个现成对象(或能转换成对象) | 可以直接传入构造参数 |
| 是否会产生临时对象 | ✅ 可能会(拷贝或移动) | ❌ 不会(直接构造) |
| 性能 | 稍慢 | 稍快(省一次拷贝或移动) |
| 出现版本 | C++98 | C++11 引入 |
🧠 二、举例理解
假设我们有一个类:
struct Worker {
Worker(int id, std::string name) {
std::cout << "construct Worker(" << id << ", " << name << ")\n";
}
};
我们想把它放进 std::vector<Worker> workers;
✳️ 用 push_back
workers.push_back(Worker(1, "Alice"));
执行过程:
-
先构造一个临时对象
Worker(1, "Alice") -
再移动或拷贝进
vector -
最后销毁临时对象
🧾 输出:
construct Worker(1, Alice)
(move or copy constructor called)
✳️ 用 emplace_back
workers.emplace_back(1, "Alice");
执行过程:
-
直接在容器内部构造这个
Worker对象 -
不会产生临时对象、也没有移动/拷贝
🧾 输出:
construct Worker(1, Alice)
🧩 三、在你的线程池中
你的代码:
workers_.emplace_back([this]{
...
});
这里:
-
workers_是std::vector<std::thread> -
emplace_back会直接在 vector 里原地创建线程对象 -
如果用
push_back,则需要先创建一个临时线程对象,再移动进去:
workers_.push_back(std::thread([this]{ ... })); // 多一次移动
所以:
✅ emplace_back 更简洁、高效、推荐使用。
✅ 四、总结一句话
push_back是 “放一个已经建好的对象进去”;
emplace_back是 “直接在容器里建这个对象”。