list::splice 比 insert+遍历快因不复制节点、仅调整指针,单次操作为 o(1);三种调用分别对应整链搬移、单节点搬移、迭代器区间搬移;需防迭代器失效、空区间静默及跨容器前提错误。

list::splice 为什么比 insert + 遍历快得多
因为 splice 不复制节点,只调整指针。哪怕源 list 有上万节点,只要目标位置已知,它就是 O(1) 操作;而用 insert 逐个插入,是 O(n) 时间 + O(n) 内存分配开销。
三种 splice 调用方式对应不同合并场景
关键看你要把哪段“搬过去”,以及插到哪里:
-
dest.splice(dest.end(), src):把整个src搬到dest尾部(src变空) -
dest.splice(it, src, src_it):把src中单个节点(由src_it指向)搬到dest的it前面 -
dest.splice(it, src, src_first, src_last):把[src_first, src_last)左闭右开区间内的节点整体搬走(注意:不是值区间,是迭代器区间)
容易踩的坑:迭代器失效和空 range 判定
搬完后,被移动节点的原迭代器(如 src_it)仍有效,但指向的是新容器;而 src 中被移走的那段,其迭代器在 src 中变成悬垂(dangling),不能再解引用。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
特别注意:splice 对空区间不报错也不做任何事——比如 src_first == src_last,调用会静默返回。所以如果逻辑依赖“是否真搬了”,得自己先判断:if (src_first != src_last) dest.splice(it, src, src_first, src_last);
跨容器 splice 的前提条件
必须是同类型 std::list(比如都是 list<int></int>),且不能是同一个对象(即 dest 和 src 不能是同一变量)。C++11 起允许移动语义,但 splice 本身不触发拷贝或移动构造——它只改指针,所以元素类型无需可拷贝,甚至不可拷贝类型(如 unique_ptr)也能安全 splice。
最常被忽略的一点:splice 的第三个重载(区间版)要求 src_first 和 src_last 都属于 src,且 src_first 可达 src_last(中间能通过 ++ 走到)。拿错容器的迭代器、或顺序反了(比如传了 src.end(), src.begin()),行为未定义。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










