std::forward_list

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

起始

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值