C++ vector怎么合并 C++ insert函数拼接两个vector的方法【容器】

8次阅读

vector insert 通过迭代器范围在指定位置插入另一vector元素:末尾用a.insert(a.end(),b.begin(),b.end()),开头用a.insert(a.begin(),b.begin(),b.end()),索引i处用a.insert(a.begin()+i,b.begin(),b.end()),需确保i合法。

C++ vector怎么合并 C++ insert函数拼接两个vector的方法【容器】

vector insert 怎么把另一个 vector 插入到指定位置

insert 本身不“合并”,而是“在某处插入一段元素”。要把 b 全部插到 a 的末尾(模拟合并),得用 a.insert(a.end(), b.begin(), b.end())。这里关键不是“拼接”这个动作,而是选对插入位置和迭代器范围。

常见错误是写成 a.insert(a.end(), b) —— insert 没有接收整个 vector 的重载,编译直接报错:no matching function for call to 'std::vector::insert(..., std::vector&)'。

  • 想插到开头:用 a.insert(a.begin(), b.begin(), b.end())
  • 想插到索引 i 处:用 a.insert(a.begin() + i, b.begin(), b.end()),但要确保 i ,越界会 undefined behavior
  • 如果 b 很大,insert 可能触发多次内存重分配,性能不如先 reserve

更自然的合并写法:用 insert + end 还是用 assign/swap

单纯“把两个 vector 合成一个”,insert(a.end(), b.begin(), b.end()) 是最直觉的,但要注意它修改的是 ab 不变。如果后续不再需要 b,可以省点拷贝开销:

  • a.insert(a.end(), std::make_move_iterator(b.begin()), std::make_move_iterator(b.end()))c++11 起),让 b 中元素被移动而非复制,前提是元素类型支持移动
  • 如果想“用 a 和 b 构造新 vector”,直接 std::vector c(a); c.insert(c.end(), b.begin(), b.end()); 更清晰,避免副作用
  • 别用 assign 来合并 —— 它会先清空目标容器,不适合追加

为什么不能直接用 operator+ 或 +=

std::vector 没有内置的 ++= 运算符重载。有人误以为像 Python 列表一样能写 a + b,结果编译失败:invalid operands to binary expression ('std::vector' and 'std::vector')

立即学习C++免费学习笔记(深入)”;

这不是遗漏,而是设计取舍:vector 是连续内存容器,隐式拼接可能掩盖性能问题(比如反复扩容)。C++ 把控制权交还给开发者,所以你必须显式调用 insertresize + copy,或封装成函数。

  • 自己写个 concat 辅助函数没问题,但别指望标准库提供
  • 第三方库如 range-v3 提供 views::concat,但那是视图(view),不拥有数据,也不等价于真正合并两个 vector

insert 合并时容易忽略的细节

看似一行代码的事,实际有几个隐蔽坑:

  • ba 类型必须严格一致(包括 const/volatile 限定),否则迭代器不能互换,编译失败
  • 如果 a 是空容器,a.end() 等价于 a.begin(),没问题;但如果 b 也是空,insert 什么也不做,这行为正确但容易让人困惑“为什么没反应”
  • 迭代器失效:插入过程中若触发扩容,a 原有所有迭代器、引用、指针全部失效 —— 所以别在 insert 后继续用之前保存的 a.begin() 之类
  • 移动插入后,b 处于有效但未指定状态(比如 string 可能为空,int vector 可能 size=0),不能再读它的元素

合并 vector 最稳妥的做法,就是明确谁是目标、谁是源,用 insert 配合 begin/end 迭代器,并在大数据量时提前 reserve。其它花招要么不可靠,要么掩盖了真实成本。

text=ZqhQzanResources