1. 简介
forward_list是一个单链表结构的容器,支持从容器中的任何位置快速插入和删除元素,不支持快速随机访问。与std::list相比,其不是双向迭代的,但该容器节省了存储空间;
头文件和定义
#include <forward_list>
template<
class T,
class Allocator = std::allocator<T>
> class forward_list;
2. 初始化
初始化分为直接初始化,拷贝初始化和赋值初始化;
/*
* @brief forward_list
* g++ -g forward_list_main.cc -o d -std=c++11
*
*/
#include <iostream>
#include <forward_list>
#include <string>
#include <iterator>
template<typename T>
void showInfo(T &t)
{
for(auto &au : t)
{
std::cout<<au<<" ";
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::forward_list<int32_t> fl_1;
fl_1 = {11,21,31,41,51,61};
showInfo(fl_1);
std::forward_list<int32_t> fl_2{100,200,300};
showInfo(fl_2);
std::forward_list<int32_t> fl_3 = fl_1;
showInfo(fl_3);
std::forward_list<std::string> fl_4 = {"c++","c","python","shell"};
showInfo(fl_4);
return 0;
}
输出
11 21 31 41 51 61
100 200 300
11 21 31 41 51 61
c++ c python shell
3. 使用
3.1 元素的访问
forward_list不支持下标访问,例如at()和[]
方法 | 说明 |
---|---|
front | 链表头元素 |
iterator | 迭代器访问元素 |
3.2 元素的大小
forward_list没有size()函数,可以通过distance来计算容器的大小;
方法 | 说明 |
---|---|
empty | 数组判空 |
max_size | 最大容量 |
resize | 改变大小 |
clear | 清空size大小 |
swap | 交换两个forward_list的内容 |
示例
int main(int argc, char *argv[])
{
std::forward_list<int32_t> fl_1;
fl_1 = {11,21,31,41,51,61};
auto begin_iter = fl_1.begin();
auto end_iter = fl_1.end();
auto size = std::distance(begin_iter,end_iter);
std::cout<<"size is: "<<size<<std::endl;
fl_1.resize(100);
begin_iter = fl_1.begin();
end_iter = fl_1.end();
size = std::distance(begin_iter,end_iter);
std::cout<<"size is: "<<size<<std::endl;
return 0;
}
结果
size is: 6
size is: 100
3.3 元素的修改
主要包括元素的赋值、插入和删除等,相关的操作和list还是存在差异
方法 | 说明 |
---|---|
assign | 重新对list赋值 |
= | 直接赋值 |
get_allocator | 返回内存分配器 |
insert_after | 在迭代器之后插入元素 |
emplace_after | 在迭代器之后插入元素 |
push_front | 头部插入元素,先复制元素,在将元素插入到头部 |
emplace_front | 头部插入元素,直接在数组尾部创建元素 |
erase_after | 删除迭代器位置之后的元素 |
pop_front | 删除头部元素 |
int main(int argc, char *argv[])
{
std::forward_list<std::string> fl_1{"c++","c","python","shell","java"};
showInfo(fl_1);
std::cout<<std::endl;
fl_1.insert_after(fl_1.begin(), "R"); //第二个元素
showInfo(fl_1);
std::cout<<std::endl;
fl_1.insert_after(fl_1.before_begin(),"golang"); //是首元素
showInfo(fl_1);
std::cout<<std::endl;
fl_1.emplace_after(fl_1.begin(),"php"); //成为第二个元素
showInfo(fl_1);
std::cout<<std::endl;
fl_1.push_front("Qt"); //插入到队列头
showInfo(fl_1);
std::cout<<std::endl;
fl_1.emplace_front("matlab"); //插入到队列头
showInfo(fl_1);
std::cout<<std::endl;
fl_1.pop_front(); //删除元素
showInfo(fl_1);
std::cout<<std::endl;
fl_1.erase_after(fl_1.begin()); //删除fl_1队列中的第二个元素
//fl_1.erase_after(fl_1.before_begin()); //删除fl_1队列中的第一个元素
showInfo(fl_1);
return 0;
}
结果
c++ c python shell java
c++ R c python shell java
golang c++ R c python shell java
golang php c++ R c python shell java
Qt golang php c++ R c python shell java
matlab Qt golang php c++ R c python shell java
Qt golang php c++ R c python shell java
Qt php c++ R c python shell java
3.4 元素的操作
方法 | 说明 |
---|---|
merge | 将forward_list2以递增的顺序合并两个forward_list1中,forward_list1中的元素不会进行排序 |
splice_after | 剪贴函数,将forward_list1中的元素剪贴到forward_list2中,将其放在之后 |
remove | 删除指定值的元素 |
remove_if | 删除指定条件的元素 |
reverse | 反序 |
unique | 去重 |
sort | 排序 |
int main(int argc, char *argv[])
{
std::forward_list<int32_t> fl_1;
fl_1 = {11,21,31,41,51,61};
showInfo(fl_1);
std::forward_list<int32_t> fl_2{25,55,300};
showInfo(fl_2);
auto iter = fl_1.begin();
//std::advance(iter, 2);
fl_1.splice_after(iter,fl_2); //放在begin的后面
showInfo(fl_1);
return 0;
}
输出
11 21 31 41 51 61
25 55 300
11 25 55 300 21 31 41 51 61
3.5 迭代器
迭代器和list相比有所不同,增加了befor_begin相关操作,但是没有rbegin等相关操作;
迭代器最好结合STL中的算法一起使用;迭代器的返回值最好用auto接受;
迭代器的类型包括:iterator、const_iterator、reverse_iterator和const_reverse_iterator
方法 | 说明 |
---|---|
begin | 返回forward_list的头元素(迭代器),其值可修改 |
end | 返回forward_list的尾元素(迭代器),其值可修改 |
cbegin | 返回forward_list的头元素(迭代器),其值不可修改,const属性 |
cend | 返回forward_list尾元素(迭代器),其值不可修改,const属性 |
befor_begin | 返回forward_list的头元素之前的位置(迭代器) |
cbefor_begin | 返回forward_list的头元素之前的位置(迭代器),const属性 |
示例
int main(int argc, char *argv[])
{
std::forward_list<int32_t> fl_1;
fl_1 = {11,21,31,41,51,61};
auto iter_1 = fl_1.begin(); //std::forward_list<int32_t>::iterator
auto iter_2 = fl_1.cbegin(); //std::forward_list<int32_t>::const_iterator
auto iter_3 = fl_1.end(); //std::forward_list<int32_t>::iterator
auto iter_4 = fl_1.cend(); //std::forward_list<int32_t>::const_iterator
auto iter_5 = fl_1.before_begin(); //std::forward_list<int32_t>::iterator
auto iter_6 = fl_1.cbefore_begin(); //std::forward_list<int32_t>::const_iterator
std::cout<<"begin() \t" << *iter_1 << std::endl;
std::cout<<"cbegin() \t" << *iter_2 << std::endl;
while (iter_1 != iter_3)
{
std::cout<<*iter_1<<" ";
iter_1++;
}
std::cout<<std::endl;
while (iter_2 != iter_4)
{
std::cout<<*iter_2<<" ";
iter_2++;
}
std::cout<<std::endl;
std::advance(iter_5,1); //向前移动1个位置
std::cout<<"before_begin() \t\t" << *iter_5 << std::endl;
std::advance(iter_6,2); //向前移动2个位置
std::cout<<"cbefore_begin() \t" << *iter_6 << std::endl;
return 0;
}
结果
begin() 11
cbegin() 11
11 21 31 41 51 61
11 21 31 41 51 61
before_begin() 11
cbefore_begin() 21
迭代器的辅助函数
辅助函数的使用需要包含头文件
#include <iterator>
方法 | 说明 |
---|---|
advance | 移动迭代器的位置 |
distance | 计算两个迭代器的距离 |
begin | 返回容器第一个元素的迭代器 |
end | 返回容器最后一个元素的迭代器 |
prev | 迭代器向前移动一个元素 |
next | 迭代器向后移动一个元素 |