Namespaces
Variants

std::list<T,Allocator>:: merge

From cppreference.net

void merge ( list & other ) ;
(1) (自 C++26 起为 constexpr)
void merge ( list && other ) ;
(2) (自 C++11 起)
(自 C++26 起为 constexpr)
template < class Compare >
void merge ( list & other, Compare comp ) ;
(3) (自 C++26 起为 constexpr)
template < class Compare >
void merge ( list && other, Compare comp ) ;
(4) (自 C++11 起)
(自 C++26 起为 constexpr)

将两个已排序列表合并为一个有序列表。

  • 如果 other * this 指向同一对象,则不执行任何操作。
  • 否则,将 other 中的所有元素转移到 * this 。合并后 other 将为空。

此操作是稳定的:

  • 对于两个列表中相等的元素,来自 * this 的元素始终位于来自 other 的元素之前。
  • * this other 中相等元素的顺序不会改变。
1,2) 等价于 merge ( other, std:: less < T > ( ) ) (C++14 前) merge ( other, std:: less <> ( ) ) (C++14 起)
3,4) 使用 comp 对元素进行比较。
若满足以下任意条件,则行为未定义:
  • * this other 未相对于比较器 comp 有序
  • get_allocator ( ) == other. get_allocator ( ) false

不会使任何迭代器或引用失效。指向从 * this 移出元素的指针和引用,以及指向这些元素的迭代器,将仍然指向 * this 中的相同元素,而非指向 other

目录

参数

other - 待合并的另一容器
comp - 比较函数对象(即满足 Compare 要求的对象),当第一个参数 小于 (即排序在 之前 )第二个参数时返回​ true

比较函数的签名应等价于如下形式:

bool cmp ( const Type1 & a, const Type2 & b ) ;

虽然签名不需要包含 const & ,但函数不得修改传递给它的对象,且必须能够接受所有(可能为const的) Type1 Type2 类型的值,无论其 值类别 为何(因此不允许 Type1& ,也不允许 Type1 ,除非对于 Type1 类型移动操作等价于拷贝操作 (C++11 起) )。
类型 Type1 Type2 必须使得 list < T, Allocator > :: const_iterator 类型的对象在解引用后能隐式转换到这两个类型。 ​

类型要求
-
Compare 必须满足 Compare 的要求。

异常

如果因任何原因抛出异常,这些函数将不产生任何效果( 强异常安全保证 )。除非异常来自比较操作。

复杂度

如果 other * this 指向同一对象,则不执行任何比较操作。

否则,给定 N 1 std:: distance ( begin ( ) , end ( ) ) N 2 std:: distance ( other. begin ( ) , other. end ( ) )

1,2) 最多使用 N 1 +N 2 -1 次比较,通过 operator < 实现。
3,4) 最多 N 1 +N 2 -1 次比较函数 comp 的应用。

示例

#include <iostream>
#include <list>
std::ostream& operator<<(std::ostream& ostr, const std::list<int>& list)
{
    for (const int i : list)
        ostr << ' ' << i;
    return ostr;
}
int main()
{
    std::list<int> list1 = {5, 9, 1, 3, 3};
    std::list<int> list2 = {8, 7, 2, 3, 4, 4};
    list1.sort();
    list2.sort();
    std::cout << "list1: " << list1 << '\n';
    std::cout << "list2: " << list2 << '\n';
    list1.merge(list2);
    std::cout << "merged:" << list1 << '\n';
}

输出:

list1:  1 3 3 5 9
list2:  2 3 4 4 7 8
merged: 1 2 3 3 3 4 4 5 7 8 9

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 适用版本 发布时行为 正确行为
LWG 300 C++98 * this other 指向
同一对象时的行为未作规定
规定为无操作
LWG 1207 C++98 未明确迭代器和/或引用是否会失效 保持有效
LWG 1215 C++98 get_allocator ( ) ! = other. get_allocator ( )
无法保证 O(1) 节点移动
此情况下
行为未定义
LWG 3088 C++98 operator < 对指针元素可能行为异常 使用实现定义的
严格全序关系

参见

从另一个 list 转移元素
(公开成员函数)
合并两个已排序范围
(函数模板)
原地合并两个有序范围
(函数模板)
合并两个已排序范围
(算法函数对象)
原地合并两个有序范围
(算法函数对象)