定义于头文件 <forward_list>
template< class T, | (1) | (C++11 起) |
namespace pmr { template <class T> | (2) | (C++17 起) |
std::forward_list 是支持从容器中的任何位置快速插入和移除元素的容器。不支持快速随机访问。它实现为单链表,且实质上与其在 C 中实现相比无任何开销。与 std::list 相比,此容器提在不需要双向迭代时提供更有效地利用空间的存储。
在链表内或跨数个链表添加、移除和移动元素,不会非法化当前指代链表中其他元素的迭代器。然而,在从链表移除元素(通过 erase_after )时,指代对应元素的迭代器或引用会被非法化。
std::forward_list 满足容器 (Container) (除了 operator== 的复杂度始终为线性和 size 函数)、具分配器容器 (AllocatorAwareContainer) 和序列容器 (SequenceContainer) 的要求。
操作
移除满足特定标准的元素
std::forward_list<T,Allocator>::remove, remove_if
void remove( const T& value ); | (C++11 起) (C++20 前) | |
size_type remove( const T& value ); | (C++20 起) | |
template< class UnaryPredicate > | (C++11 起) (C++20 前) | |
template< class UnaryPredicate > | (C++20 起) |
移除所有满足特定标准的元素。第一版本移除所有等于 value
的元素,第二版本移除所有谓词 p
对它返回 true 的元素。
参数
value | - | 要移除的元素的值 |
p | - | 若应该移除该元素则返回 true 的一元谓词。 对每个(可为 const 的) |
返回值
(无) | (C++20 前) |
移除的元素数。 | (C++20 起) |
复杂度
与容器大小成线性
将该链表的所有元素的顺序反转
std::forward_list<T,Allocator>::reverse
void reverse() noexcept; | (C++11 起) |
逆转容器中的元素顺序。不非法化任何引用或迭代器。
参数
(无)
返回值
(无)
复杂度
与容器大小成线性
删除连续的重复元素
std::forward_list<T,Allocator>::unique
void unique(); | (1) | (C++11 起) (C++20 前) |
size_type unique(); | (C++20 起) | |
template< class BinaryPredicate > | (2) | (C++11 起) (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 起) |
复杂度
与容器大小成线性
对元素进行排序
std::forward_list<T,Allocator>::sort
void sort(); | (1) | (C++11 起) |
template< class Compare > | (2) | (C++11 起) |
以升序排序元素。保持相等元素的顺序。第一版本用 operator< 比较元素,第二版本用给定的比较函数 comp
。
若抛出异常,则 *this 中元素顺序未指定。
参数
comp | - | 比较函数对象(即满足比较 (Compare) 概念的对象),若第一参数小于(即先序于)第二参数则返回 true 。 比较函数的签名应等价于如下: bool cmp(const Type1 &a, const Type2 &b); 虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 |
返回值
(无)
复杂度
大约 N log N 次比较,其中 N 是表中的元素数。
注意
std::sort 要求随机访问迭代器且不能用于 forward_list
。此函数与 std::sort 的区别在于,它不要求 forward_list
的元素类型可交换,保留所有迭代器的值,并进行稳定排序。
调用示例
#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
using namespace std;
struct Cell
{
int x;
int y;
Cell() = default;
Cell(int a, int b): x(a), y(b) {}
Cell &operator +=(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
Cell &operator +(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
Cell &operator *(const Cell &cell)
{
x *= cell.x;
y *= cell.y;
return *this;
}
Cell &operator ++()
{
x += 1;
y += 1;
return *this;
}
bool operator <(const Cell &cell) const
{
if (x == cell.x)
{
return y < cell.y;
}
else
{
return x < cell.x;
}
}
bool operator ==(const Cell &cell) const
{
return x == cell.x && y == cell.y;
}
};
std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
os << "{" << cell.x << "," << cell.y << "}";
return os;
}
int main()
{
std::cout << std::boolalpha;
std::mt19937 g{std::random_device{}()};
srand((unsigned)time(NULL));
auto generate = []()
{
int n = std::rand() % 10 + 100;
Cell cell{n, n};
return cell;
};
std::forward_list<Cell> forward_list1(6);
std::generate(forward_list1.begin(), forward_list1.end(), generate);
std::cout << "forward_list1: ";
std::copy(forward_list1.begin(), forward_list1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//移除所有满足特定标准的元素。第一版本移除所有等于 value 的元素
forward_list1.remove(*(forward_list1.begin()));
std::cout << "forward_list1 remove: ";
std::copy(forward_list1.begin(), forward_list1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
auto func_remove = [](const Cell & a, const Cell & b)
{
return a.x == b.x && a.y == b.y;
};
//移除所有满足特定标准的元素。第二版本移除所有谓词 p 对它返回 true 的元素。
forward_list1.remove_if(std::bind(func_remove, std::placeholders::_1, *(forward_list1.begin())));
std::cout << "forward_list1 remove_if: ";
std::copy(forward_list1.begin(), forward_list1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
std::forward_list<Cell> forward_list2(6);
std::generate(forward_list2.begin(), forward_list2.end(), generate);
std::cout << "forward_list2: ";
std::copy(forward_list2.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//逆转容器中的元素顺序。不非法化任何引用或迭代器。
forward_list2.reverse();
std::cout << "forward_list2 reverse: ";
std::copy(forward_list2.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
std::cout << std::endl;
auto func_sort = [](const Cell & a, const Cell & b)
{
if (a.x == b.x)
{
return a.y > b.y;
}
return a.x > b.x;
};
auto func_unique = [](const Cell & a, const Cell & b)
{
return a.x == b.x && a.y == b.y;
};
for (size_t index = 0; index < 3; index++)
{
std::forward_list<Cell> forward_list(6);
std::generate(forward_list.begin(), forward_list.end(), generate);
std::cout << "forward_list " << index + 3 << ": ";
std::copy(forward_list.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//对元素进行排序
if (index % 2 == 0)
{
// 升序
forward_list.sort();
}
else
{
// 降序
forward_list.sort(func_sort);
}
std::cout << "forward_list " << index + 3 << " sort: ";
std::copy(forward_list.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//从容器移除所有相继的重复元素。
if (index % 2 == 0)
{
//第一版本用 operator== 比较元素
forward_list.unique();
}
else
{
//第二版本用二元谓词 p 比较元素
forward_list.unique(func_unique);
}
std::cout << "forward_list " << index + 3 << " unique: ";
std::copy(forward_list.begin(), forward_list2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
}
return 0;
}
输出