std::forward_list
来源:互联网 发布:unix环境高级编程源码 编辑:程序博客网 时间:2024/06/06 07:39
http://classfoo.com/ccby/article/5wWLx
- // <forward_list>
- template < class T, class Alloc = allocator<T> > class forward_list;
正向列表(Forward list)是一个允许在序列中任何一处位置以常量耗时插入或删除元素的顺序容器(Sequence container)。
A forward_list is a container that supports forward iterators and allows constant time insert and erase operations anywhere within the sequence, with storage management handled automatically.
容性特性:
(1)顺序序列
顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。
(2)单链表
容器中的每个元素保存了定位前一个元素及后一个元素的信息,允许在任何一处位置以常量耗时进行插入或删除操作,但不能进行直接随机访问(Direct random access)。
(3)能够感知内存分配器的(Allocator-aware)
容器使用一个内存分配器对象来动态地处理它的存储需求。
模板参数
T :存储在容器中的元素的数据类型。在类模板内部,使用其别名为
value_type
的成员类型。Alloc :容器内部用来管理内存分配及释放的内存分配器的类型。
这个参数是可选的,它的默认值是
std::allocator<T>
,这个是一个最简单的非值依赖的(Value-independent)内存分配器。 在类模板内部,使用其别名为allocator_type
的成员类型。详细说明
标准模板库(Standard Template Library,简称STL)中的正向列表容器采用的是单链表(Singly-linked lists)数据库构。单链表可以保存以不同且无关的储存位置容纳的元素。元素间的顺序是通过各个元素中指向下一个元素的链接这一联系维护的。
该特点跟
std:: list
容器的有点相似:主要的区别就是std:: list
的元素中不仅保存了指向下一个元素的链接,还保存了指向上一个元素的链接,这使得std::list
允许双向迭代,但消耗更多的存储空间且在插入删除元素时会有稍高(Slight higher)的耗时。因此std::forward_list
对象比std::list
对象更高效,尽管它们只能正向迭代。增加或移动正向列表中的元素不会使指向它们的指针、引用、迭代器失效,只有当对应的元素被销毁时才会如此。
相比较于其它的基本标准顺序容器(数组
std::array
、向量std::vector
、双端队列std::deque
等),正向列表通常在容器中已获得迭代器的任意位置处插入、获得(Extracting,提取)、移动元素等操作中表现出更出色的性能,对那些密集使用上述操作的算法,使用正向列表同样能提升性能,比如排序算法。双向链表(
std::list
)及正向链表(std:: forward_list
)相比于其它顺序容器的主要缺点是它们不能够通过元素在容器中的位置直接访问(Direct access)元素。举个例子:如果想访问一个正向列表中的第六个元素,那么就必须从一个已知位置(比如开头或末尾)处开始迭代,这会消耗与两个位置之间距间相关的线性时间。而且它们还为保存各个元素间的链接信息消耗更多额外的内存(这点对由小尺寸元素组成而元素数较大的正向列表尤为明显)。Fast random access to list elements is not supported.
forward_list
类模板是专为极度考虑性能的程序而设计的,它就跟自实现的C型单链表(C-style singly-linked list)一样高效。甚至为了性能,它是唯一一个缺少size
成员函数的标准容器:这是出于其单链表的性质,如果拥有size
成员函数,就必须消耗常量时间来维护一个用于保存当前容器大小的内部计数器,这会消耗更多的存储空间,且使得插入及删除操作略微降低性能。如果想获得forward_list
的大小,可以使用std::distance
算法且传递forward_list::begin
及forward_list::end
参数,该操作的时间复杂度为 O(n)。对任意列表(std::list)进行插入或删除元素操作需要访问插入位置前的元素,但对 forward_list 来说访问该元素没有常数时间(Constant-time)的方法。因为这个原因,对传递给清除(Erase)、拼接(Splice)等成员函数的范围参数作了修改,这些范围必须为开区间(即不包括末尾元素的同时也不包括起始元素)。
Modifying any list requires access to the element preceding the first element of interest, but in a forward_list there is no constant-time way to acess a preceding element. For this reason, ranges that are modified, such as those supplied to erase and splice, must be open at the beginning.
成员类型
成员类型 定义 value_type
第一个模板参数 Tallocator_type
第二个模板参数 Allocsize_type
无符号整数类型(通常为size_t
)difference_type
有符号整数类型(通常为ptrdiff_t
)reference
value_type&
const_reference
const value_type&
pointer
std::allocator_traits<Allocator>::pointer
const_pointer
std::allocator_traits<Allocator>::const_pointer
iterator
正向迭代器const_iterator
常正向迭代器成员函数
(constructor)创建forward_list
(destructor)释放forward_list
operator=
值赋操作Iterators:
before_begin
返回指向容器起始位置前的迭代器(iterator
)begin
返回指向容器起始位置的迭代器end
返回指向容器末尾下一个位置的迭代器cbefore_begin
返回指向容器起始位置前的常迭代器(const_iterator
)cbegin
返回指向容器起始位置的常迭代器cend
返回指向容器末尾下一个位置的常迭代器Capacity:
empty
判断是否为空max_size
返回forward_list
支持的最大元素个数Element access:
front
访问第一个元素Modifiers:
assign
将新的内容赋值给容器emplace_front
在容器开头构造及插入一个元素push_front
在容器开头插入一个元素pop_front
删除第一个元素emplace_after
构造及插入一个元素insert_after
插入元素erase_after
删除元素swap
交换内容resize
改变有效元素的个数clear
清空内容Operations:
splice_after
使元素从一个正向列表移动到另一个正向列表remove
删除值为指定值的元素remove_if
删除满足指定条件的元素unique
删除重复值merge
合并已排序的正向列表sort
为容器中的所有元素排序reverse
反转元素的顺序Observers:
get_allocator
获得内存分配器非成员函数
operator==、operator!=、operator<、operator<=、operator>、operator>=关系操作符std::swap
交换两个正向列表的内容算法相关 <algorithm> 头文件中包含大量与 forward_list 容器相关的算法
搜索算法std::adjacent_find
、std::count、
std::count_if
、std::find、
std::find_if
、std::find_end、
std::find_first_of
、std::search、
std::search_n
、std::equal、
std::mismatch
二分查找(Binary search)std::lower_bound
、std::upper_bound、
std::equal_range
、std::binary_search
集合(Set)操作std::includes
、std::set_difference、
std::set_intersection
、std::set_union、
std::set_symmetric_difference
最大与最小std::min_element
、std::max_element
字典序比较std::lexicographical_compare
排列生成器std::next_permutation
、std::prev_permutation
其它操作std::all_of
、std::any_of
、std::none_of
、std::for_each
、std::copy
、std::copy_if
、std::copy_n
、std::copy_backward
、std::move
、std::move_backward
、std::swap_ranges
、std::iter_swap
、std::transform
、std::replace
、
std::replace_if
、std::replace_copy
、std::replace_copy_if
、std::fill
、std::fill_n
、std::generate
、std::generate_n
、std::remove
、std::remove_if
、std::unique
、std::unique_copy
、std::reverse
、std::reverse_copy
、std::rotate
、std::rotate_copy
、std::random_shuffle
、std::shuffle
、std::partition
、std::is_partitioned
、std::stable_partition
、
std::partition_copy
、std::merge
具体内容详见各个功能函数。除了排序(
std::sort
等)、堆操作(std::make_heap
、std::sort_heap
等)、第n个元素(std::nth_element
),适用于std::vector
的例子基本上都适用于std::forward_list
,可以参考 vector 与算法 主题,该主题包含大量的代码示例。代码示例
综合
下面这个例子简单地介绍了
forward_list
的常用使用方法。- #include <iostream>
- #include <forward_list>
- #include <numeric>
- #include <algorithm>
- namespace ClassFoo{
- using namespace std;
- void ForwardListExample1(){
- forward_list<int> foo1;
- forward_list<int>::iterator it;
- //从前面向foo1容器中添加数据
- foo1.push_front (2);
- foo1.push_front (1);
- foo1.push_front (14);
- foo1.push_front (17);
- //按从小到大排序
- foo1.sort();
- cout<<"foo1中的元素"<<endl;
- for (it = foo1.begin(); it != foo1.end(); ++it)
- cout << *it << " ";
- cout << endl;
- //使用STL的accumulate(累加)算法
- int result = accumulate(foo1.begin(), foo1.end(),0);
- cout<<"和为:"<<result<<endl;
- //使用STL的max_element算法求foo2中的最大元素并显示
- it=max_element(foo1.begin(),foo1.end());
- cout << "最大元素是: "<< *it <<endl;
- }
- }
- int main()
- {
- ClassFoo::ForwardListExample1();
- return 0;
- }
输出:
foo1中的元素
1 2 14 17
和为:34
最大元素是: 17
一个有用的宏
虽然 C++11 中已经开始支持初始化列表,但可能您的编译器还未支持(即使已经支持 C++11),此时,可以使用如下等效的解决方案。
- #define CLASSFOO_FORWARD_LIST(type, name, ...) \
- static const type name##_a[] = __VA_ARGS__; \
- std::forward_list<type> name(name##_a, name##_a + sizeof(name##_a) / sizeof(*name##_a))
可以这样使用:
- CLASSFOO_FORWARD_LIST(int,foo,{1,2,3,4,5,6,7});
- std::forward_list
- std::forward_list
- QLinkedList和std::forward_list
- forward_list
- C++11中std::forward_list单向链表的使用
- 【C++ STL应用与实现】7: 如何使用std::forward_list 单链表 (since C++11)
- STL forward_list
- stl::forward_list
- C++容器之forward_list
- C++ forward_list::::insert_after
- STL list和forward_list
- c++11之forward_list
- STL容器forward_list
- c++ forward_list 的使用
- std
- std
- std
- 顺序容器forward_list[c++11]
- 3.2.5.3 search()函数和match()函数区别
- 排序算法时间复杂度对比
- ZOJ 2412 Farm Irrigation
- vuGen回放https录制出错
- jQuery-选择器
- std::forward_list
- POJ2337 Catenyms(欧拉回路+dfs)
- js 与或运算符 || && 妙用
- 结构体、结构指针作为函数参数
- mysql优化sql语句步骤
- STL — 关联容器
- 命令行(The Command Line is Your Best Friend)
- Java 单例模式几种实现的差别
- 87 thinkphp 和sql查询条件为某字段不为空的情况