标准模板库(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.