std::back_inserter本身不扩容,真正扩容的是目标容器调用push_back时的内部逻辑;它仅包装push_back调用,要求容器支持非const push_back成员函数,适用于vector、deque、list等,不适用于array、set、map或const容器。

std::back_inserter 为什么能自动扩容
std::back_inserter 本身不扩容,它只是包装一个 push_back 调用器。真正扩容的是目标容器(如 std::vector、std::deque)在执行 push_back 时的内部逻辑。它返回一个输出迭代器,每次解引用(*it = x)实际等价于调用 container.push_back(x)。
这意味着:只有支持 push_back 的容器才能用 std::back_inserter —— std::list、std::vector、std::deque 可以;std::array、std::set、std::map 不行。
常见误用:传给不支持 push_back 的容器
典型错误是试图对 std::array 或空 std::vector 用 std::back_inserter 却没预留空间(其实不是预留问题,而是根本不能用):
std::array<int, 5> arr; auto it = std::back_inserter(arr); // 编译失败:no member named 'push_back'
另一个隐蔽坑是传入 const 容器引用:
立即学习“C++免费学习笔记(深入)”;
const std::vector<int> v; auto it = std::back_inserter(v); // 编译失败:cannot bind non-const lvalue reference
- 确保容器类型有非 const 的
push_back成员函数 - 传入的必须是非 const 左值引用(
std::vector<int>&</int>,不能是const std::vector<int>&</int>或临时对象) - 不要和
std::inserter混用——后者用于任意位置插入,需指定迭代器位置
配合算法使用的典型场景
最常用在 std::copy、std::transform、std::fill_n 等需要输出迭代器的算法中,避免手动预分配或循环 push:
std::vector<int> src = {1, 2, 3};
std::vector<int> dst;
std::copy(src.begin(), src.end(), std::back_inserter(dst)); // 自动扩容三次
注意:如果已知元素数量,直接 reserve 可减少重分配次数,但 std::back_inserter 本身不感知容量,也不负责优化:
-
dst.reserve(src.size())推荐放在std::back_inserter使用前 -
std::back_inserter对std::list同样有效,但list无容量概念,扩容即分配新节点 - 对
std::deque,push_back通常很快,但内部是分段连续,不保证内存连续
和普通迭代器赋值的区别
直接用 dst.end() 作为输出迭代器是错的——它不是输出迭代器,且 *dst.end() = x 是未定义行为:
std::vector<int> dst; // ❌ 错误:dst.end() 是 past-the-end,不可解引用 std::copy(src.begin(), src.end(), dst.end()); // 运行时崩溃或静默损坏
std::back_inserter 的关键价值在于把“追加语义”编码进迭代器类型系统里:
- 它是一个
std::back_insert_iterator<container></container>实例,重载了operator=去调用push_back - 它不关心当前容器大小或容量,只响应赋值操作
- 不能用于随机访问(比如
it + 1),仅支持*it = x和++it(后者通常空操作)
容器是否扩容、何时扩容、扩容多少,完全由其自身实现决定;std::back_inserter 只是触发它的安全接口。别指望它做容量预测或内存池管理。










