list::merge仅合并已按相同规则排序的另一list,不支持vector等其他容器,也不执行排序,仅归并;若结果乱序,通常因被合并list未排序或排序规则不一致。

list::merge 只接受另一个 list 且要求已排序
list::merge 不是通用合并函数,它只支持将另一个 std::list 合并进当前 list,并且**两个 list 都必须已按相同规则升序排列**(或都降序)。它不接受 vector、array 或裸指针链表;也不做排序,只做归并(merge),类似归并排序中的 merge 步骤。
常见错误现象:list1.merge(list2) 后结果乱序 → 很可能 list2 本身未排序,或两 list 排序规则不一致(比如一个用 ,另一个用自定义比较器但没传给 merge)。
- 调用前确保
list2已排序,且与list1使用同一比较逻辑 - 若需不同排序规则,必须显式传入比较器:
list1.merge(list2, std::greater()) -
list2在 merge 后变为空 —— 这是标准行为,所有节点被移入list1
merge 后原 list2 为空,不能重复使用
这是最容易忽略的副作用。list::merge 是“移动式”合并:它把 list2 的所有节点直接拼接到 list1 中,不复制节点,也不保留 list2 的内容。执行后 list2.empty() 必为 true。
如果你误以为 list2 还能继续参与下一次 merge(比如循环中反复合并),程序会逻辑错误——后续调用实际在合并一个空 list。
立即学习“C++免费学习笔记(深入)”;
- 需要复用数据时,要么重新构造
list2,要么改用std::merge算法(输出到第三方容器) - 调试时可加断言验证:
assert(list2.empty()); - 注意:即使传了比较器,
list2仍会被清空
和 std::merge 算法的关键区别
std::merge(在 中)是更通用的归并函数,适用于任意有序范围(如两个 vector 的区间),但它**不修改输入容器,而是将结果写入目标迭代器**;而 list::merge 是成员函数,就地修改 *this,并清空参数 list。
使用场景差异:
- 想保持两个源 list 不变?用
std::merge(l1.begin(), l1.end(), l2.begin(), l2.end(), back_inserter(result)) - 想节省内存、避免复制节点,且允许
list2被清空?用l1.merge(l2) -
std::merge要求输出容器有足够空间或支持插入(如std::back_inserter),list::merge则无此负担
自定义类型必须提供可比性或显式传比较器
如果 list 调用 merge,编译器需要能比较两个 MyClass 对象。默认情况下,它依赖 operator;若未定义,或你想用其他逻辑(如按 id 升序、按 name 降序),就必须传比较器。
错误示例:my_list.merge(other_list); 编译失败,提示 “no match for ‘operator
- 补全
operator:在MyClass中声明bool operator - 或调用时传 lambda:
list1.merge(list2, [](const auto& a, const auto& b) { return a.id - 注意:该比较器必须与两个 list 当前的元素顺序一致,否则结果未定义
真正要注意的是:merge 不检查排序正确性,只按你给的比较逻辑线性归并。哪怕 list 看似有序但违反了你传的比较器语义(比如比较器用 > 但 list 实际按 排),结果一定错,而且很难 debug。










