std::forward_list
介绍
成员函数
非成员函数
介绍
// forward_list 模板定义
template<class T, class Allocator = std::allocator<T>> class forward_list; (C++11 起)
namespace pmr {
template <class T>
using forward_list = std::forward_list<T, std::pmr::polymorphic_allocator<T>>;
} (C++17 起)
- std::forward_list 介绍摘选自 cppreference.com 中文网 std::forward_list 介绍
- std::forward_list 是支持从容器中的任何位置快速插入和移除元素的容器,不支持快速随机访问
- 它实现为单链表,且实质上与其在 C 中实现相比无任何开销
- 与 std::list 相比,此容器在不需要双向迭代时提供更有效地利用空间的存储
- 在链表内或跨数个链表添加、移除和移动元素,不会非法化当前指代链表中其他元素的迭代器
- 在从链表移除元素(通过 erase_after )时,指代对应元素的迭代器或引用会被非法化
成员函数
构造析构
#include <QCoreApplication>
#include <algorithm>
#include <forward_list>
#include <iostream>
#include <string>
auto Print(const std::string &msg, const std::forward_list<int> &lst) {
std::cout << msg << " : ";
for (auto iter = lst.begin(); iter != lst.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using list_int = std::forward_list<int>;
list_int l1; //默认构造
Print("l1", l1);
std::allocator<int> alloc;
list_int l2(alloc); //设置分配器
Print("l2", l2);
list_int l3(5, -1, alloc); //设置元素数量,初始值,分配器
Print("l3", l3);
list_int l4(5); //设置元素数量
Print("l4", l4);
list_int l5(l3.begin(), l3.end()); //迭代器初始化
Print("l5", l5);
list_int l6(l5); //容器拷贝初始化,可设置分配器
Print("l6", l6);
list_int l7(l6, alloc);
Print("l7", l7);
list_int l8(std::move(l7)); //容器移动构造初始化,可设置分配器
Print("l8", l8);
list_int l9(std::move(l8), alloc);
Print("l9", l9);
list_int l10{0, 2, 4, 6, 8, 10}; //初始化列表
Print("l10", l10);
return 0; // a.exec();
}
输出结果:
l1 :
l2 :
l3 : -1 -1 -1 -1 -1
l4 : 0 0 0 0 0
l5 : -1 -1 -1 -1 -1
l6 : -1 -1 -1 -1 -1
l7 : -1 -1 -1 -1 -1
l8 : -1 -1 -1 -1 -1
l9 : -1 -1 -1 -1 -1
l10 : 0 2 4 6 8 10
元素访问
auto Print(const std::string &msg, const std::forward_list<int> &lst) {
std::cout << msg << " : ";
for (auto iter = lst.begin(); iter != lst.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using list_int = std::forward_list<int>;
list_int l1{1, 3, 5, 7, 9};
Print("l1", l1);
std::cout << "index 0 : " << l1.front() << std::endl; //访问第一个元素
std::cout << "index 0 : " << l1.front() << std::endl; //访问第一个元素
return 0; // a.exec();
}
输出结果:
l1 : 1 3 5 7 9
index 0 : 1
index 0 : 1
迭代器
auto Print(const std::string &msg, const std::forward_list<int> &lst) {
std::cout << msg << " : ";
for (auto iter = lst.begin(); iter != lst.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using list_int = std::forward_list<int>;
list_int l1{1, 3, 5, 7, 9};
Print("l1", l1);
//返回指向首元素前一元素的迭代器。此元素表现为占位符,试图访问它会导致未定义行为。仅有的使用情况是在函数
// insert_after() 、 emplace_after() 、 erase_after() 、 splice_after()
//和迭代器自增中:自增始前迭代器准确地给出与从 begin()/cbegin()
//获得者相同的迭代器。
list_int::iterator biter = l1.before_begin();
list_int::const_iterator cbiter = l1.cbefore_begin();
list_int::iterator iter = l1.begin();
std::cout << "l1 : ";
for (; iter != l1.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
list_int::const_iterator citer = l1.begin();
std::cout << "l1 : ";
for (; citer != l1.end(); ++citer) {
std::cout << *citer << "\t";
}
std::cout << "\n";
return 0; // a.exec();
}
输出结果:
l1 : 1 3 5 7 9
l1 : 1 3 5 7 9
l1 : 1 3 5 7 9
容量
auto Print(const std::string &msg, const std::forward_list<int> &lst) {
std::cout << msg << " : ";
for (auto iter = lst.begin(); iter != lst.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using list_int = std::forward_list<int>;
list_int l1{1, 3, 5, 7, 9};
Print("l1", l1);
std::cout << std::boolalpha << "test.empty : " << l1.empty()
<< "\n"; // 检查容器是否为空
std::cout << "test.max_size : " << l1.max_size()
<< "\n"; // 返回可容纳的最大元素数,和平台有关
return 0; // a.exec();
}
输出结果:
l1 : 1 3 5 7 9
test.empty : false
test.max_size : 1152921504606846975
修改器
auto Print(const std::string &msg, const std::forward_list<int> &lst) {
std::cout << msg << " : ";
for (auto iter = lst.begin(); iter != lst.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using list_int = std::forward_list<int>;
list_int l1{1, 3, 5, 7, 9};
Print("l1", l1);
l1.clear(); // 清除内容
Print("l1", l1);
l1.insert_after(l1.cbefore_begin(), 10); //在某个元素后插入新元素
Print("l1", l1);
l1.emplace_after(l1.cbefore_begin(), 20); //在元素后原位构造元素
Print("l1", l1);
l1.erase_after(l1.cbegin()); //擦除元素后的元素
Print("l1", l1);
l1.push_front(30); //插入元素到容器起始
Print("l1", l1);
l1.emplace_front(40); //在容器头部原位构造元素
Print("l1", l1);
l1.pop_front(); //移除首元素
Print("l1", l1);
l1.resize(10); //改变容器中可存储元素的个数
Print("l1", l1);
list_int l2{2, 4, 6, 8, 10};
Print("l2", l2);
l1.swap(l2); //交换内容
Print("l1", l1);
Print("l2", l2);
return 0; // a.exec();
}
输出结果:
l1 : 1 3 5 7 9
l1 :
l1 : 10
l1 : 20 10
l1 : 20
l1 : 30 20
l1 : 40 30 20
l1 : 30 20
l1 : 30 20 0 0 0 0 0 0 0 0
l2 : 2 4 6 8 10
l1 : 2 4 6 8 10
l2 : 30 20 0 0 0 0 0 0 0 0
操作
auto Print(const std::string &msg, const std::forward_list<int> &lst) {
std::cout << msg << " : ";
for (auto iter = lst.begin(); iter != lst.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using list_int = std::forward_list<int>;
list_int l1{1, 3, 5, 7, 9};
list_int l2{2, 4, 6, 8, 10};
Print("l1", l1);
Print("l2", l2);
l1.merge(l2); //合并二个已排序列表
Print("l1", l1);
Print("l2", l2);
list_int l3{10, 20, 30};
l1.splice_after(l1.before_begin(), l3); //从另一 forward_list 移动元素
Print("l1", l1);
l1.remove(20); //移除满足特定标准的元素
Print("l1", l1);
l1.remove_if([](int v) -> bool { return v > 20; });
Print("l1", l1);
l1.reverse(); //将该链表的所有元素的顺序反转
Print("l1", l1);
list_int l4{2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 3, 3, 5};
l4.unique(); //删除连续的重复元素
Print("l4", l4);
list_int l5{5, 6, 1, 2, 4};
l5.sort(); //对元素进行排序
Print("l5", l5);
return 0; // a.exec();
}
输出结果:
l1 : 1 3 5 7 9
l2 : 2 4 6 8 10
l1 : 1 2 3 4 5 6 7 8 9 10
l2 :
l1 : 10 20 30 1 2 3 4 5 6 7 8 9 10
l1 : 10 30 1 2 3 4 5 6 7 8 9 10
l1 : 10 1 2 3 4 5 6 7 8 9 10
l1 : 10 9 8 7 6 5 4 3 2 1 10
l4 : 2 3 4 3 5
l5 : 1 2 4 5 6
非成员函数
auto Print(const std::string &msg, const std::forward_list<int> &lst) {
std::cout << msg << " : ";
for (auto iter = lst.begin(); iter != lst.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using list_int = std::forward_list<int>;
list_int l1{1, 3, 5, 7, 9};
list_int l2{2, 4, 6, 8, 10};
Print("l1", l1);
Print("l2", l2);
std::cout.setf(std::ios::boolalpha);
std::cout << "l1 == l2 : " << (l1 == l2) << std::endl;
std::cout << "l1 != l2 : " << (l1 != l2) << std::endl;
std::cout << "l1 > l2 : " << (l1 > l2) << std::endl;
std::cout << "l1 >= l2 : " << (l1 >= l2) << std::endl;
std::cout << "l1 < l2 : " << (l1 < l2) << std::endl;
std::cout << "l1 <= l2 : " << (l1 <= l2) << std::endl;
std::cout.unsetf(std::ios::boolalpha);
// c++20 废弃以上操作符重载,提供三路运算符 operator <=> ()
std::swap(l1, l2);
Print("l1", l1);
Print("l2", l2);
return 0; // a.exec();
}
输出结果:
l1 : 1 3 5 7 9
l2 : 2 4 6 8 10
l1 == l2 : false
l1 != l2 : true
l1 > l2 : false
l1 >= l2 : false
l1 < l2 : true
l1 <= l2 : true
l1 : 2 4 6 8 10
l2 : 1 3 5 7 9