定义于头文件 <list>
template< class T, class Allocator = std::allocator<T> > class list; (1)
namespace pmr { template <class T>
using list = std::list<T, std::pmr::polymorphic_allocator<T>>;} (2) (C++17 起)
std::list 是支持常数时间从容器任何位置插入和移除元素的容器。不支持快速随机访问。它通常实现为双向链表。与 std::forward_list 相比,此容器提供双向迭代但在空间上效率稍低。
在 list 内或在数个 list 间添加、移除和移动元素不会非法化迭代器或引用。迭代器仅在对应元素被删除时非法化。
std::list 满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、序列容器 (SequenceContainer) 及可逆容器 (ReversibleContainer) 的要求。
删除连续的重复元素
std::list<T,Allocator>::unique
void unique(); | (1) | (C++20 前) | |
size_type unique(); | (C++20 起) | ||
template< class BinaryPredicate > | (2) | (C++20 前) | |
template< class BinaryPredicate > | (C++20 起) |
从容器移除所有相继的重复元素。只留下相等元素组中的第一个元素。第一版本用 operator==
比较元素,第二版本用二元谓词 p
比较元素
参数
p | - | 若元素应被当做相等则返回 true 的二元谓词。 谓词函数的签名应等价于如下: bool pred(const Type1 &a, const Type2 &b); 虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 |
返回值
(无) | (C++20 前) |
移除的元素数。 | (C++20 起) |
复杂度
与容器大小成线性
调用示例
#include <iostream>
#include <list>
int main()
{
std::list<int> x = {1, 2, 2, 3, 3, 2, 1, 1, 2};
std::cout << "contents before:";
for (auto val : x)
{
std::cout << ' ' << val;
}
std::cout << '\n';
x.unique();
std::cout << "contents after unique():";
for (auto val : x)
{
std::cout << ' ' << val;
}
std::cout << '\n';
return 0;
}
输出
对元素进行排序
std::list<T,Allocator>::sort
void sort(); | (1) |
template< class Compare > | (2) |
以升序排序元素。保持相等元素的顺序。第一版本用 operator< 比较元素,第二版本用给定的比较函数 comp
。
若抛出异常,则 *this 中元素顺序未指定。
参数
comp | - | 比较函数对象(即满足比较 (Compare) 概念的对象),若第一参数小于(即先序于)第二参数则返回 true 。 比较函数的签名应等价于如下: bool cmp(const Type1 &a, const Type2 &b); 虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 |
返回值
(无)
复杂度
大约 N log N 次比较,其中 N 是表中的元素数。
注意
std::sort 要求随机访问迭代器且不能用于 list
。此函数与 std::sort 的区别在于,它不要求 list
的元素类型可交换,保留所有迭代器的值,并进行稳定排序。
调用示例
#include <iostream>
#include <functional>
#include <list>
std::ostream& operator<<(std::ostream& ostr, const std::list<int>& list)
{
for (auto &i : list)
{
ostr << " " << i;
}
return ostr;
}
int main()
{
std::list<int> list = { 8, 7, 5, 9, 0, 1, 3, 2, 6, 4 };
std::cout << "before: " << list << "\n";
list.sort();
std::cout << "ascending: " << list << "\n";
list.sort(std::greater<int>());
std::cout << "descending: " << list << "\n";
}
输出
按照字典顺序比较 list 中的值
operator==,!=,<,<=,>,>=(std::list)
template< class T, class Alloc > bool operator==( const std::list<T,Alloc>& lhs, const std::list<T,Alloc>& rhs ); | (1) |
template< class T, class Alloc > bool operator!=( const std::list<T,Alloc>& lhs, const std::list<T,Alloc>& rhs ); | (2) |
template< class T, class Alloc > bool operator<( const std::list<T,Alloc>& lhs, const std::list<T,Alloc>& rhs ); | (3) |
template< class T, class Alloc > bool operator<=( const std::list<T,Alloc>& lhs, const std::list<T,Alloc>& rhs ); | (4) |
template< class T, class Alloc > bool operator>( const std::list<T,Alloc>& lhs, const std::list<T,Alloc>& rhs ); | (5) |
template< class T, class Alloc > bool operator>=( const std::list<T,Alloc>& lhs, const std::list<T,Alloc>& rhs ); | (6) |
比较二个容器的内容。
1-2) 检查 lhs
与 rhs
的内容是否相等,即它们是否拥有相同数量的元素且 lhs
中每个元素与 rhs
的同位置元素比较相等。
3-6) 按字典序比较 lhs
与 rhs
的内容。由等价于 std::lexicographical_compare 的函数进行比较。
参数
lhs, rhs | - | 要比较内容的容器 |
- 为使用重载 (1-2) , T 必须满足可相等比较 (EqualityComparable) 的要求。 | ||
- 为使用重载 (3-6) , T 必须满足可小于比较 (LessThanComparable) 的要求。顺序关系必须建立全序。 |
返回值
1) 若容器内容相等则为 true ,否则为 false
2) 若容器内容不相等则为 true ,否则为 false
3) 若 lhs
的内容按字典序小于 rhs
的内容则为 true ,否则为 false
4) 若 lhs
的内容按字典序小于或等于 rhs
的内容则为 true ,否则为 false
5) 若 lhs
的内容按字典序大于 rhs
的内容则为 true ,否则为 false
6) 若 lhs
的内容按字典序大于或等于 rhs
的内容则为 true ,否则为 false
复杂度
1-2) 若 lhs
与 rhs
的大小不同则为常数,否则与容器大小成线性
3-6) 与容器大小成线性
调用示例
#include <iostream>
#include <list>
int main()
{
std::list<int> list1 = { 1, 2, 3};
std::list<int> list2 = { 1, 2, 3, 4};
std::list<int> list3 = { 3, 2, 1};
std::list<int> list4 = { 3 };
std::list<int> list5;
std::list<int> list6 = {1, 2, 3};
std::cout << std::boolalpha << "list1 == list2 " << (list1 == list2) << std::endl;
std::cout << std::boolalpha << "list1 != list3 " << (list1 != list3) << std::endl;
std::cout << std::boolalpha << "list1 > list4 " << (list1 > list4) << std::endl;
std::cout << std::boolalpha << "list1 >= list5 " << (list1 >= list5) << std::endl;
std::cout << std::boolalpha << "list1 < list6 " << (list1 < list6) << std::endl;
std::cout << std::boolalpha << "list2 <= list5 " << (list1 <= list5) << std::endl;
}
输出
特化 std::swap 算法
std::swap(std::list)
template< class T, class Alloc >
void swap( list<T,Alloc>& lhs,
list<T,Alloc>& rhs ); (C++17 前)
template< class T, class Alloc >
void swap( list<T,Alloc>& lhs,
list<T,Alloc>& rhs ) noexcept(/* see below */); (C++17 起)
为 std::list 特化 std::swap 算法。交换 lhs
与 rhs
的内容。调用 lhs.swap(rhs) 。
参数
lhs, rhs | - | 要交换内容的容器 |
返回值
(无)
复杂度
常数。
异常
noexcept 规定: noexcept(noexcept(lhs.swap(rhs))) | (C++17 起) |
调用示例
#include <iostream>
#include <list>
std::ostream& operator<<(std::ostream& ostr, const std::list<int>& list)
{
for (auto &i : list)
{
ostr << " " << i;
}
return ostr;
}
int main()
{
std::list<int> list1 = { 1, 2, 3, 4, 5 };
std::list<int> list2 = { 10, 20, 30, 40, 50 };
std::cout << "swap before list1: " << list1 << "\n";
std::cout << "swap before list2: " << list2 << "\n\n";
std::swap(list1, list2);
std::cout << "swap after list1: " << list1 << "\n";
std::cout << "swap after list2: " << list2 << "\n";
}