顺序容器:list双向链表 详解

目录

前言

一、定义及初始化

[1.定义 list 对象](#1.定义 list 对象)

2.初始化方式

[二、向 list 对象中添加元素](#二、向 list 对象中添加元素)

1.在前端添加元素

2.在后端添加元素

3.在中间插入元素

[三、list 常用迭代器](#三、list 常用迭代器)

[四、list 常用运算符](#四、list 常用运算符)

[五、list 常用成员函数](#五、list 常用成员函数)

[1.empty 成员函数](#1.empty 成员函数)

[2.size 成员函数](#2.size 成员函数)

[3.front 成员函数](#3.front 成员函数)

[4.push_front 成员函数](#4.push_front 成员函数)

[5.pop_front 成员函数](#5.pop_front 成员函数)

[6.back 成员函数](#6.back 成员函数)

[7.push_back 成员函数](#7.push_back 成员函数)

[8.pop_back 成员函数](#8.pop_back 成员函数)

[9.insert 成员函数](#9.insert 成员函数)

[10.erase 成员函数](#10.erase 成员函数)

[11.swap 成员函数](#11.swap 成员函数)

[12.clear 成员函数](#12.clear 成员函数)

[六、list 特有成员函数](#六、list 特有成员函数)

[1.merge 特有成员函数](#1.merge 特有成员函数)

[2.remove 特有成员函数](#2.remove 特有成员函数)

[3.remove_if 特有成员函数](#3.remove_if 特有成员函数)

[4.reverse 特有成员函数](#4.reverse 特有成员函数)

[5.sort 特有成员函数](#5.sort 特有成员函数)

[6.splice 特有成员函数](#6.splice 特有成员函数)

[7.unique 特有成员函数](#7.unique 特有成员函数)

七、综合练习

[练习 1:list 基本操作](#练习 1:list 基本操作)

[练习 2:使用 list 特有成员函数](#练习 2:使用 list 特有成员函数)

[练习 3:使用 list 实现一个简单的链表](#练习 3:使用 list 实现一个简单的链表)


前言

STL中的list是一个双向循环链表,如下图所示:

第一个参数是任何数据类型,第二个参数可有可无。

list对象自带两个指针,一个指向第一个元素,另一个指向最后一个元素。

因此list在如下几个主要方面与array、 vector 或deque不同:

●list不支持随机访问,如果你要访问第5个元素,就得顺着链表逐一遍历前 4个元素。所以,在 list中随机访问任意元素是很缓慢的。然而访问第一个和最后一个元素的速度很快。

●任何位置(不只两端)插入和删除 都非常快,在常量时间内完成,因为无须移动其他元素。只需要进行一些指针操作。

list提供的比较好用的函数:

●list提供front,push_front,pop_front和back,push_back,pop_back等函数

●由于不支持随机访问,list即不支持下标操作也不支持at函数。

●list提供不少特殊成员函数,专门用于移动和删除元素,和同名的STL通用算法相比,这些函数执行起来更快速,优先使用list自己提供的算法。

一、定义及初始化

list 是 C++ 标准库中的一个双向链表容器,定义在 <list> 头文件中,位于 std 命名空间内。它支持在任意位置高效地插入和删除元素,但不支持随机访问。

使用list时必须先包含头文件<list>:

cpp 复制代码
#include <list>

1.定义 list 对象

cpp 复制代码
#include <list>

// 定义一个存储 int 类型的 list
std::list<int> lst;

// 定义一个存储 std::string 类型的 list
std::list<std::string> strLst;

2.初始化方式

  1. 默认初始化:创建一个空 list

    cpp 复制代码
    std::list<int> lst; // 空 list
  2. 列表初始化

    cpp 复制代码
    std::list<int> lst = {1, 2, 3, 4, 5};
    std::list<int> lst2{1, 2, 3, 4, 5}; // 与上面等价
  3. 指定元素个数和初始值

    cpp 复制代码
    std::list<int> lst(5, 10); // 包含 5 个元素,每个元素值为 10
  4. 使用另一个 list 初始化

    cpp 复制代码
    std::list<int> lst1 = {1, 2, 3, 4, 5};
    std::list<int> lst2 = lst1; // 拷贝初始化
    std::list<int> lst3(lst1); // 拷贝构造
  5. 使用迭代器范围初始化

    cpp 复制代码
    std::list<int> lst1 = {1, 2, 3, 4, 5};
    std::list<int> lst2(lst1.begin(), lst1.end()); // 包含 lst1 的所有元素
    
    // 从其他容器初始化
    std::vector<int> vec = {6, 7, 8, 9, 10};
    std::list<int> lst3(vec.begin(), vec.end()); // 包含 vec 的所有元素

二、向 list 对象中添加元素

list 支持在任意位置高效地添加元素,尤其是在两端和已知位置。

1.在前端添加元素

  1. push_front 成员函数

    • 功能:在 list 前端添加一个元素
    • 参数:要添加的元素值
    • 返回值:无
    cpp 复制代码
    std::list<int> lst = {2, 3, 4};
    lst.push_front(1); // lst 现在包含 {1, 2, 3, 4}
  2. emplace_front 成员函数(C++11)

    • 功能:在 list 前端直接构造一个元素
    • 参数:构造元素所需的参数
    • 返回值:无
    • 优点:避免了额外的拷贝或移动操作,比 push_front 更高效
    cpp 复制代码
    std::list<std::pair<int, std::string>> lst;
    lst.emplace_front(1, "one"); // 直接在前端构造 pair 对象
    lst.push_front({2, "two"}); // 先构造临时 pair 对象,再移动到前端

2.在后端添加元素

  1. push_back 成员函数

    • 功能:在 list 后端添加一个元素
    • 参数:要添加的元素值
    • 返回值:无
    cpp 复制代码
    std::list<int> lst = {1, 2, 3};
    lst.push_back(4); // lst 现在包含 {1, 2, 3, 4}
    lst.push_back(5); // lst 现在包含 {1, 2, 3, 4, 5}
  2. emplace_back 成员函数(C++11)

    • 功能:在 list 后端直接构造一个元素
    • 参数:构造元素所需的参数
    • 返回值:无
    • 优点:避免了额外的拷贝或移动操作,比 push_back 更高效
    cpp 复制代码
    std::list<std::pair<int, std::string>> lst;
    lst.emplace_back(1, "one"); // 直接在后端构造 pair 对象
    lst.push_back({2, "two"}); // 先构造临时 pair 对象,再移动到后端

3.在中间插入元素

  1. insert 成员函数

    • 功能:在指定位置插入元素
    • 参数
      • 版本 1:pos, value - 在迭代器 pos 前插入 value
      • 版本 2:pos, count, value - 在迭代器 pos 前插入 count 个 value
      • 版本 3:pos, first, last - 在迭代器 pos 前插入迭代器范围 [first, last) 中的元素
    • 返回值:指向新插入的第一个元素的迭代器
    • 说明:在 list 中插入元素的效率很高,因为只需要修改指针,不需要移动元素
    cpp 复制代码
    std::list<int> lst = {1, 2, 4, 5};
    
    // 在位置 2 前插入元素 3
    auto it = lst.begin();
    std::advance(it, 2); // 将迭代器移动到位置 2
    lst.insert(it, 3); // lst 现在包含 {1, 2, 3, 4, 5}
    
    // 在位置 0 前插入 2 个 0
    lst.insert(lst.begin(), 2, 0); // lst 现在包含 {0, 0, 1, 2, 3, 4, 5}
    
    // 在末尾插入另一个 list 的元素
    std::list<int> lst2 = {6, 7, 8};
    lst.insert(lst.end(), lst2.begin(), lst2.end()); // lst 现在包含 {0, 0, 1, 2, 3, 4, 5, 6, 7, 8}
  2. emplace 成员函数(C++11)

    • 功能:在指定位置直接构造一个元素
    • 参数
      • pos - 插入位置的迭代器
      • 构造元素所需的参数
    • 返回值:指向新构造元素的迭代器
    • 优点:避免了额外的拷贝或移动操作
    cpp 复制代码
    std::list<std::pair<int, std::string>> lst;
    auto it = lst.begin();
    lst.emplace(it, 1, "one"); // 直接在指定位置构造 pair 对象

三、list 常用迭代器

list 容器提供了多种迭代器类型,用于遍历容器中的元素。需要注意的是,list 的迭代器是双向迭代器,不支持随机访问(如 it + 5 这样的操作)。

|-------------|-----------------------------|
| 迭代器 | 含义 |
| l.begin() | 第一个元素的迭代器 |
| l.end() | 最后一个元素的下一个位置迭代器(尾后迭代器或尾迭代器) |
| l.cbegin() | 第一个元素的常量迭代器(不修改元素内容) |
| l.cend() | 尾后常量迭代器(不修改元素内容) |
| l.rbegin() | 从后往前的第一个迭代器 |
| l.rend() | 从后往前的最后一个迭代器 |
| l.crbegin() | 从后往前的第一个常量迭代器 |
| l.crend() | 从后往前的最后一个常量迭代器 |

使用示例:

cpp 复制代码
std::list<int> lst = {1, 2, 3, 4, 5};

// 使用正向迭代器遍历
for (auto it = lst.begin(); it != lst.end(); ++it) {
    std::cout << *it << " "; // 输出: 1 2 3 4 5
}
std::cout << std::endl;

// 使用反向迭代器遍历
for (auto it = lst.rbegin(); it != lst.rend(); ++it) {
    std::cout << *it << " "; // 输出: 5 4 3 2 1
}
std::cout << std::endl;

// 使用常量迭代器遍历(不能修改元素)
for (auto it = lst.cbegin(); it != lst.cend(); ++it) {
    std::cout << *it << " "; // 输出: 1 2 3 4 5
    // *it = 10; // 错误:常量迭代器不能修改元素
}
std::cout << std::endl;

// 移动迭代器
auto it = lst.begin();
std::advance(it, 2); // 将迭代器移动 2 个位置
std::cout << "Element at position 2: " << *it << std::endl; // 输出: 3

四、list 常用运算符

list 类重载了多种运算符,方便容器操作:

  1. 赋值运算符

    • =:将一个 list 赋值给另一个 list
    cpp 复制代码
    std::list<int> lst1 = {1, 2, 3};
    std::list<int> lst2;
    lst2 = lst1; // lst2 现在包含 {1, 2, 3}
  2. 比较运算符

    • ==:判断两个 list 是否相等
    • !=:判断两个 list 是否不相等
    • <:判断一个 list 是否小于另一个 list(字典序)
    • <=:判断一个 list 是否小于或等于另一个 list
    • >:判断一个 list 是否大于另一个 list
    • >=:判断一个 list 是否大于或等于另一个 list
    cpp 复制代码
    std::list<int> lst1 = {1, 2, 3};
    std::list<int> lst2 = {1, 2, 4};
    bool b1 = (lst1 == lst2); // false
    bool b2 = (lst1 < lst2);  // true(第三个元素 3 < 4)

五、list 常用成员函数

|--------------------|-----------------------------|
| list l的成员函数 | 含义 |
| l.empty() | 判断是否为空 |
| l.size() | 返回 l 的数据个数 ,重要函数 |
| l.front() | 返回第一个元素的引用 ,重要函数 |
| l.push_front() | 头插 ,重要函数 |
| l.pop_front() | 头删 ,重要函数 |
| l.back() | 返回最后一个元素的引用 ,重要函数 |
| l.push_back() | 尾插 ,重要函数 |
| l.pop_back() | 尾删 ,重要函数 |
| l.insert() | 插入一个或多个元素,这个效率为常数 ,重要函数 |
| l.erase() | 删除一个或多个元素 ,重要函数 |
| l.swap() | 交换两个list的值 ,重要函数 |
| l.clear() | 清空数据 |

1.empty 成员函数

  • 功能:判断 list 是否为空
  • 参数:无
  • 返回值 :如果 list 为空返回 true,否则返回 false
cpp 复制代码
std::list<int> lst1;
std::list<int> lst2 = {1, 2, 3};
std::cout << lst1.empty(); // 输出: 1 (true)
std::cout << lst2.empty(); // 输出: 0 (false)

2.size 成员函数

  • 功能:返回 list 中元素的个数
  • 参数:无
  • 返回值 :元素个数,类型为 size_t
cpp 复制代码
std::list<int> lst = {1, 2, 3, 4, 5};
std::cout << lst.size(); // 输出: 5

3.front 成员函数

  • 功能:返回 list 中第一个元素的引用
  • 参数:无
  • 返回值:第一个元素的引用
  • 说明:如果 list 为空,行为未定义
cpp 复制代码
std::list<int> lst = {1, 2, 3};
std::cout << lst.front(); // 输出: 1
lst.front() = 10;         // lst 现在包含 {10, 2, 3}

4.push_front 成员函数

  • 功能:在 list 前端添加一个元素
  • 参数:要添加的元素值
  • 返回值:无
cpp 复制代码
std::list<int> lst = {2, 3, 4};
lst.push_front(1); // lst 现在包含 {1, 2, 3, 4}

5.pop_front 成员函数

  • 功能:删除 list 前端的一个元素
  • 参数:无
  • 返回值:无
  • 说明:如果 list 为空,行为未定义
cpp 复制代码
std::list<int> lst = {1, 2, 3, 4};
lst.pop_front(); // lst 现在包含 {2, 3, 4}
lst.pop_front(); // lst 现在包含 {3, 4}

6.back 成员函数

  • 功能:返回 list 中最后一个元素的引用
  • 参数:无
  • 返回值:最后一个元素的引用
  • 说明:如果 list 为空,行为未定义
cpp 复制代码
std::list<int> lst = {1, 2, 3};
std::cout << lst.back(); // 输出: 3
lst.back() = 30;         // lst 现在包含 {1, 2, 30}

7.push_back 成员函数

  • 功能:在 list 后端添加一个元素
  • 参数:要添加的元素值
  • 返回值:无
cpp 复制代码
std::list<int> lst = {1, 2, 3};
lst.push_back(4); // lst 现在包含 {1, 2, 3, 4}
lst.push_back(5); // lst 现在包含 {1, 2, 3, 4, 5}

8.pop_back 成员函数

  • 功能:删除 list 后端的一个元素
  • 参数:无
  • 返回值:无
  • 说明:如果 list 为空,行为未定义
cpp 复制代码
std::list<int> lst = {1, 2, 3, 4, 5};
lst.pop_back(); // lst 现在包含 {1, 2, 3, 4}
lst.pop_back(); // lst 现在包含 {1, 2, 3}

9.insert 成员函数

  • 功能:在指定位置插入元素
  • 参数
    • 版本 1:pos, value - 在迭代器 pos 前插入 value
    • 版本 2:pos, count, value - 在迭代器 pos 前插入 count 个 value
    • 版本 3:pos, first, last - 在迭代器 pos 前插入迭代器范围 [first, last) 中的元素
  • 返回值:指向新插入的第一个元素的迭代器
cpp 复制代码
std::list<int> lst = {1, 2, 4, 5};

// 在位置 2 前插入元素 3
auto it = lst.begin();
std::advance(it, 2); // 将迭代器移动到位置 2
lst.insert(it, 3); // lst 现在包含 {1, 2, 3, 4, 5}

10.erase 成员函数

  • 功能:删除 list 中的元素
  • 参数
    • 版本 1:pos - 删除迭代器 pos 指向的元素
    • 版本 2:first, last - 删除迭代器范围 [first, last) 中的元素
  • 返回值:指向被删除元素之后位置的迭代器
cpp 复制代码
std::list<int> lst = {1, 2, 3, 4, 5};

// 删除位置 2 的元素
auto it = lst.begin();
std::advance(it, 2); // 将迭代器移动到位置 2
it = lst.erase(it); // lst 现在包含 {1, 2, 4, 5},it 指向 4

// 删除从位置 1 到位置 2 的元素
auto start = lst.begin();
std::advance(start, 1); // 移动到位置 1
auto end = start;
std::advance(end, 2); // 移动到位置 3
lst.erase(start, end); // lst 现在包含 {1, 5}

11.swap 成员函数

  • 功能:交换两个 list 的内容
  • 参数:另一个 list 对象
  • 返回值:无
cpp 复制代码
std::list<int> lst1 = {1, 2, 3};
std::list<int> lst2 = {4, 5, 6};
lst1.swap(lst2); // lst1 现在包含 {4, 5, 6},lst2 现在包含 {1, 2, 3}

12.clear 成员函数

  • 功能:删除 list 中的所有元素
  • 参数:无
  • 返回值:无
cpp 复制代码
std::list<int> lst = {1, 2, 3, 4, 5};
lst.clear();
std::cout << lst.size(); // 输出: 0
std::cout << lst.empty(); // 输出: 1 (true)

六、list 特有成员函数

|------------------|--------------|
| list l特有成员函数 | 含义 |
| l.merge() | 链表合并 |
| l.remove(val) | 删除所有和val相同元素 |
| l.remove_if() | 删除符合条件的元素 |
| l.reverse() | 反转链表中的元素 |
| l.sort() | 排序(默认为升序) |
| l.splice() | 链表连结 |
| l.unique() | 删除重复元素 |

1.merge 特有成员函数

  • 功能:合并两个已排序的 list
  • 参数
    • other - 另一个已排序的 list
  • 返回值:无
  • 说明:合并后,other 变为空
cpp 复制代码
std::list<int> lst1 = {1, 3, 5};
std::list<int> lst2 = {2, 4, 6};
lst1.merge(lst2); // lst1 现在包含 {1, 2, 3, 4, 5, 6},lst2 为空

2.remove 特有成员函数

  • 功能:删除所有值等于指定值的元素
  • 参数:要删除的值
  • 返回值:无
cpp 复制代码
std::list<int> lst = {1, 2, 3, 2, 4, 2, 5};
lst.remove(2); // lst 现在包含 {1, 3, 4, 5}

3.remove_if 特有成员函数

  • 功能:删除所有满足指定条件的元素
  • 参数:一个返回 bool 的函数对象或 lambda 表达式
  • 返回值:无
cpp 复制代码
std::list<int> lst = {1, 2, 3, 4, 5, 6};

// 删除所有偶数
lst.remove_if([](int n) { return n % 2 == 0; }); // lst 现在包含 {1, 3, 5}

4.reverse 特有成员函数

  • 功能反转 list 中元素的顺序
  • 参数:无
  • 返回值:无
cpp 复制代码
std::list<int> lst = {1, 2, 3, 4, 5};
lst.reverse(); // lst 现在包含 {5, 4, 3, 2, 1}

5.sort 特有成员函数

  • 功能 :对 list 中的元素进行排序
  • 参数:可选的比较函数
  • 返回值:无
cpp 复制代码
std::list<int> lst = {5, 2, 8, 1, 9};
lst.sort(); // lst 现在包含 {1, 2, 5, 8, 9}

// 使用自定义比较函数(降序)
lst.sort(std::greater<int>()); // lst 现在包含 {9, 8, 5, 2, 1}

6.splice 特有成员函数

  • 功能:将一个 list 中的元素转移到另一个 list 中
  • 参数
    • 版本 1:pos, other - 将 other 中的所有元素转移到 pos 前
    • 版本 2:pos, other, it - 将 other 中 it 指向的元素转移到 pos 前
    • 版本 3:pos, other, first, last - 将 other 中 [first, last) 范围内的元素转移到 pos 前
  • 返回值:无
  • 说明:转移后,原 list 中的元素被移除
cpp 复制代码
std::list<int> lst1 = {1, 2, 3};
std::list<int> lst2 = {4, 5, 6};

// 将 lst2 中的所有元素转移到 lst1 的末尾
lst1.splice(lst1.end(), lst2); 
// lst1 现在包含 {1, 2, 3, 4, 5, 6},lst2 为空

// 重新初始化 lst2
lst2 = {7, 8, 9};

// 将 lst2 中的第一个元素转移到 lst1 的开头
auto it = lst2.begin();
lst1.splice(lst1.begin(), lst2, it); 
// lst1 现在包含 {7, 1, 2, 3, 4, 5, 6},lst2 现在包含 {8, 9}

7.unique 特有成员函数

  • 功能:删除连续的重复元素,只保留一个
  • 参数:可选的比较函数
  • 返回值:无
cpp 复制代码
std::list<int> lst = {1, 1, 2, 2, 2, 3, 4, 4, 5};
lst.unique(); // lst 现在包含 {1, 2, 3, 4, 5}

七、综合练习

练习 1:list 基本操作

cpp 复制代码
#include <iostream>
#include <list>

int main() {
    // 创建并初始化 list
    std::list<int> lst = {3, 4, 5};
    
    // 在前端添加元素
    lst.push_front(2);
    lst.push_front(1);
    
    // 在后端添加元素
    lst.push_back(6);
    lst.push_back(7);
    
    // 输出当前 list
    std::cout << "Current list: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // 访问元素
    std::cout << "Front: " << lst.front() << std::endl;
    std::cout << "Back: " << lst.back() << std::endl;
    
    // 删除前端和后端元素
    lst.pop_front();
    lst.pop_back();
    
    // 输出修改后的 list
    std::cout << "After pop_front and pop_back: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // 在中间插入元素
    auto it = lst.begin();
    std::advance(it, 2);
    lst.insert(it, 10);
    
    // 输出插入后的 list
    std::cout << "After insert: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // 删除中间元素
    it = lst.begin();
    std::advance(it, 1);
    lst.erase(it);
    
    // 输出删除后的 list
    std::cout << "After erase: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // 检查 list 状态
    std::cout << "Size: " << lst.size() << std::endl;
    std::cout << "Empty: " << (lst.empty() ? "Yes" : "No") << std::endl;
    
    return 0;
}

练习 2:使用 list 特有成员函数

cpp 复制代码
#include <iostream>
#include <list>

int main() {
    // 创建并初始化 list
    std::list<int> lst = {5, 2, 8, 1, 9, 3, 7, 4, 6};
    
    // 排序
    lst.sort();
    std::cout << "After sort: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // 反转
    lst.reverse();
    std::cout << "After reverse: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // 创建另一个 list 并合并
    std::list<int> lst2 = {10, 11, 12};
    lst.merge(lst2);
    std::cout << "After merge: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    std::cout << "lst2 size: " << lst2.size() << std::endl; // 应该为 0
    
    // 添加重复元素并去重
    lst.push_back(5);
    lst.push_back(5);
    lst.push_back(7);
    std::cout << "Before unique: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    lst.unique();
    std::cout << "After unique: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // 删除特定元素
    lst.remove(5);
    std::cout << "After remove 5: ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    // 删除满足条件的元素
    lst.remove_if([](int n) { return n > 8; });
    std::cout << "After remove_if (>8): ";
    for (int x : lst) {
        std::cout << x << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

练习 3:使用 list 实现一个简单的链表

cpp 复制代码
#include <iostream>
#include <list>
#include <string>

class Student {
public:
    std::string name;
    int age;
    double score;
    
    Student(std::string n, int a, double s) : name(n), age(a), score(s) {}
    
    void display() const {
        std::cout << "Name: " << name << ", Age: " << age << ", Score: " << score << std::endl;
    }
};

// 自定义比较函数,按分数降序排序
bool compareByScore(const Student& s1, const Student& s2) {
    return s1.score > s2.score;
}

int main() {
    // 创建存储 Student 对象的 list
    std::list<Student> students;
    
    // 添加学生
    students.emplace_back("Alice", 18, 95.5);
    students.emplace_back("Bob", 19, 88.0);
    students.emplace_back("Charlie", 17, 92.5);
    students.emplace_back("David", 18, 85.0);
    
    // 显示所有学生
    std::cout << "All students: " << std::endl;
    for (const auto& student : students) {
        student.display();
    }
    
    // 按分数排序
    students.sort(compareByScore);
    std::cout << "\nStudents sorted by score: " << std::endl;
    for (const auto& student : students) {
        student.display();
    }
    
    // 删除年龄小于 18 的学生
    students.remove_if([](const Student& s) { return s.age < 18; });
    std::cout << "\nStudents after removing under 18: " << std::endl;
    for (const auto& student : students) {
        student.display();
    }
    
    // 反转顺序
    students.reverse();
    std::cout << "\nStudents in reverse order: " << std::endl;
    for (const auto& student : students) {
        student.display();
    }
    
    return 0;
}
相关推荐
楼田莉子3 小时前
CMake学习:CMake在静态库工程场景上应用
开发语言·c++·后端·学习·软件构建
森G3 小时前
28、视图基类 QAbstractItemView---------Model/View模型视图
c++·qt
不想看见4043 小时前
C++/Qt 使用 Tushare 获取股票信息
c++·qt·信息可视化
014-code3 小时前
ThreadLocal 详解
java·jvm·数据结构
Qt程序员3 小时前
深入理解 Linux 内核 RCU 机制:从原理到实现
linux·c++·内核·linux内核·rcu
吴梓穆3 小时前
UE5 c++打印日志
开发语言·c++·ue5
吴梓穆3 小时前
UE5 C++ 绘制图形调试宏
开发语言·c++·ue5
2501_908329853 小时前
C++中的装饰器模式
开发语言·c++·算法