当前位置: 首页 > news >正文

List容器:特性与操作使用指南

目录

一、List(链表)容器的详细介绍

1、基本特性

2、与 forward_list 的比较

3、性能特点

优势:

劣势:

4、适用场景

5、实现细节

二、list的定义方式

1、构造空容器

2、构造含n个val的容器

3、拷贝构造容器

4、使用迭代器范围构造

5、使用数组区间构造

6、移动构造(C++11)

7、初始化列表构造(C++11)

三、List 的插入和删除操作

1、头插和头删操作

push_front 和 pop_front

2、尾插和尾删操作

push_back 和 pop_back

3、插入操作

insert 函数

4、删除操作

erase 函数

总结

四、List迭代器的使用

1、正向迭代器

正向迭代器遍历示例

注意事项

2、反向迭代器

反向迭代器遍历示例

注意事项

3、迭代器使用场景

4、C++11后的简化写法

总结

五、List容器的首尾元素访问

1、front() 和 back() 函数

2、示例代码

3、注意事项

4、修改元素示例

六、list容器的大小控制方法

1、size() - 获取元素数量

2、resize() - 调整容器大小

3、empty() - 检查容器是否为空

4、clear() - 清空容器

总结

七、list容器操作函数

1、sort函数

2、splice函数

3、remove和remove_if函数

4、unique函数

5、merge函数

6、reverse函数

7、assign函数

8、swap函数

八、List迭代器失效问题

1、迭代器失效的概念

2、List迭代器失效的特点

3、错误示例分析

4、正确解决方案

方案1:利用后置++的特性

erase(it++) 的执行流程

具体例子

关键点

方案2:使用erase的返回值


一、List(链表)容器的详细介绍

List 是 C++ 标准模板库(STL)中的一种序列式容器,具有以下核心特性:

1、基本特性

  • 支持在常数时间 O(1) 范围内进行任意位置的插入和删除操作

  • 提供前后双向迭代的能力(双向链表结构)

  • 底层采用双向链表实现,每个元素存储在独立的节点中

  • 各节点通过前驱和后继指针相互连接

2、与 forward_list 的比较

单向链表 forward_list 的主要区别:

  • 双向迭代 vs 单向迭代

  • 更完善的操作接口(forward_list 为节省内存牺牲了部分功能)

3、性能特点

优势:

  • 任意位置插入/删除效率极高(无需移动其他元素)

  • 拼接操作(splice)性能优异

劣势:

  • 不支持随机访问(无法使用 [] 运算符)

  • 需要额外存储空间维护节点关系

  • 对缓存局部性(cache locality)不友好

4、适用场景

  • 需要频繁在序列中间进行插入/删除操作

  • 不需要随机访问元素

  • 需要高效的大型序列拼接操作

  • 元素体积较大时,链表的内存开销相对较小

5、实现细节

  • 通常采用环状双向链表实现

  • 每个节点包含:数据域、前驱指针、后继指针

  • 可能包含一个哨兵节点(dummy node)简化边界条件处理

注意:当存储小型元素且不需要频繁中间操作时,vector 通常能提供更好的综合性能。选择容器时应根据具体使用场景权衡利弊。


二、list的定义方式

        list是C++标准模板库(STL)中的一个双向链表容器,提供了多种灵活的构造方式。以下是list的几种主要定义方式:

1、构造空容器

最基本的构造方式,创建一个指定类型的空链表容器。

list<int> lt1;  // 构造一个int类型的空链表

2、构造含n个val的容器

创建一个包含n个相同元素的链表。

list<int> lt2(10, 2);  // 构造含有10个值为2的int类型链表

3、拷贝构造容器

通过另一个同类型list容器进行拷贝构造。

list<int> lt3(lt2);  // 使用lt2拷贝构造一个新的int类型链表lt3

4、使用迭代器范围构造

通过其他容器的迭代器范围来构造链表。

string s("hello world");
list<char> lt4(s.begin(), s.end());  // 使用string的迭代器范围构造char类型链表

5、使用数组区间构造

通过原生数组的区间来构造链表。

int arr[] = {1, 2, 3, 4, 5};
int sz = sizeof(arr) / sizeof(int);
list<int> lt5(arr, arr + sz);  // 使用数组区间构造int类型链表

6、移动构造(C++11)

使用移动语义构造链表,高效转移资源所有权。

list<int> temp = {1, 2, 3};
list<int> lt6(std::move(temp));  // 移动构造,temp现在为空

7、初始化列表构造(C++11)

使用初始化列表直接构造链表。

list<int> lt7 = {1, 2, 3, 4, 5};  // 使用初始化列表构造

这些构造方式提供了极大的灵活性,可以根据不同场景选择最合适的初始化方法。


三、List 的插入和删除操作

1、头插和头删操作

push_front 和 pop_front

push_front 函数用于在链表头部插入一个元素,pop_front 函数用于删除链表头部的元素。

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt;// 头部插入元素lt.push_front(0);lt.push_front(1);lt.push_front(2);// 输出当前链表内容for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 2 1 0// 头部删除元素lt.pop_front();// 输出删除后的链表内容for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 1 0return 0;
}

2、尾插和尾删操作

push_back 和 pop_back

push_back 函数用于在链表尾部插入一个元素,pop_back 函数用于删除链表尾部的元素。

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt;// 尾部插入元素lt.push_back(0);lt.push_back(1);lt.push_back(2);lt.push_back(3);// 输出当前链表内容for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 0 1 2 3// 尾部删除元素(删除两次)lt.pop_back();lt.pop_back();// 输出删除后的链表内容for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 0 1return 0;
}

3、插入操作

insert 函数

list 的 insert 函数支持三种插入方式:

  1. 在指定迭代器位置插入一个元素

  2. 在指定迭代器位置插入 n 个值为 val 的元素

  3. 在指定迭代器位置插入一段迭代器区间(左闭右开)

#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);// 在值为2的位置插入9list<int>::iterator pos = find(lt.begin(), lt.end(), 2);lt.insert(pos, 9);for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 1 9 2 3// 在值为3的位置插入2个8pos = find(lt.begin(), lt.end(), 3);lt.insert(pos, 2, 8);for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 1 9 2 8 8 3// 在值为1的位置插入vector中的元素vector<int> v(2, 7); // 包含两个7的vectorpos = find(lt.begin(), lt.end(), 1);lt.insert(pos, v.begin(), v.end());for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 7 7 1 9 2 8 8 3return 0;
}

注意find 函数是 <algorithm> 头文件中的一个函数,用于在指定迭代器区间查找指定值的位置,并返回该位置的迭代器。如果未找到,则返回结束迭代器。

4、删除操作

erase 函数

list 的 erase 函数支持两种删除方式:

  1. 删除指定迭代器位置的元素

  2. 删除指定迭代器区间(左闭右开)的所有元素

#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);// 删除值为2的元素list<int>::iterator pos = find(lt.begin(), lt.end(), 2);lt.erase(pos);for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 1 3 4 5// 删除从值为4的元素到末尾的所有元素pos = find(lt.begin(), lt.end(), 4);lt.erase(pos, lt.end());for (auto e : lt) {cout << e << " ";}cout << endl; // 输出: 1 3return 0;
}

总结

  • 头部操作push_front 和 pop_front 提供了高效的头部插入和删除

  • 尾部操作push_back 和 pop_back 提供了高效的尾部插入和删除

  • 任意位置操作insert 和 erase 提供了在任意位置插入和删除元素的能力

  • 性能特点:由于 list 是双向链表,所有插入和删除操作的时间复杂度都是 O(1)(前提是已经获得正确位置的迭代器)

这些操作使得 list 在需要频繁插入和删除元素的场景中表现出色。


四、List迭代器的使用

可暂时将迭代器理解成一个指针,该指针指向list中的某个节点。

1、正向迭代器

list容器的正向迭代器通过begin()end()函数获得:

  • begin(): 返回指向容器中第一个元素的正向迭代器

  • end(): 返回指向容器中最后一个元素的下一个位置的正向迭代器(不是最后一个元素)

正向迭代器遍历示例

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt(10, 2); // 创建包含10个值为2的元素的list// 使用正向迭代器遍历容器list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;return 0;
}

输出结果:

注意事项

  1. end()返回的是"尾后迭代器",不能解引用

  2. 迭代器支持++操作来移动到下一个元素

  3. 可以用*操作符访问当前元素的值

2、反向迭代器

list容器的反向迭代器通过rbegin()rend()函数获得:

  • rbegin(): 返回指向容器中最后一个元素的反向迭代器

  • rend(): 返回指向容器中第一个元素的前一个位置的反向迭代器

反向迭代器遍历示例

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt(10, 2); // 创建包含10个值为2的元素的list// 使用反向迭代器遍历容器list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";rit++;}cout << endl;return 0;
}

输出结果:

注意事项

  1. 反向迭代器的++操作实际上是向容器的前端移动

  2. rend()返回的是"首前迭代器",不能解引用

  3. 反向迭代器也需要用*操作符访问当前元素的值

3、迭代器使用场景

  1. 遍历容器:如上面示例所示

  2. 插入元素:使用insert()函数结合迭代器在特定位置插入元素

  3. 删除元素:使用erase()函数结合迭代器删除特定位置的元素

  4. 算法操作:与STL算法配合使用,如sort()find()

4、C++11后的简化写法

C++11引入了auto关键字,可以简化迭代器声明:

// 正向迭代器
for(auto it = lt.begin(); it != lt.end(); ++it) {cout << *it << " ";
}// 反向迭代器
for(auto rit = lt.rbegin(); rit != lt.rend(); ++rit) {cout << *rit << " ";
}// 范围for循环(C++11)
for(const auto& val : lt) {cout << val << " ";
}

总结

        list的迭代器提供了灵活访问容器元素的方式,正向迭代器适合从前向后遍历,反向迭代器适合从后向前遍历。理解迭代器的概念对于有效使用STL容器至关重要。


五、List容器的首尾元素访问

在C++ STL中,list容器提供了两个便捷的成员函数来访问首尾元素:

1、front() 和 back() 函数

  • front(): 返回list容器中的第一个元素的引用

  • back(): 返回list容器中的最后一个元素的引用

这两个函数的时间复杂度都是O(1),因为它们直接访问list的头尾节点,不需要遍历整个容器。

2、示例代码

#include <iostream>
#include <list>
using namespace std;int main()
{// 创建一个整型list并初始化list<int> lt;lt.push_back(0);  // 添加元素0lt.push_back(1);  // 添加元素1lt.push_back(2);  // 添加元素2lt.push_back(3);  // 添加元素3lt.push_back(4);  // 添加元素4// 输出第一个和最后一个元素cout << "第一个元素: " << lt.front() << endl;  // 输出: 0cout << "最后一个元素: " << lt.back() << endl;  // 输出: 4return 0;
}

3、注意事项

  1. 在调用front()back()前,应确保list不为空,否则会导致未定义行为

  2. 这两个函数返回的是引用,因此可以直接修改元素值

  3. 如果需要检查list是否为空,可以使用empty()成员函数

4、修改元素示例

lt.front() = 10;  // 将第一个元素改为10
lt.back() = 40;   // 将最后一个元素改为40

这种直接访问首尾元素的方式使得list在某些场景下(如实现队列)非常高效。


六、list容器的大小控制方法

        list是C++ STL中的一个双向链表容器,提供了多种方法来控制和查询容器的大小。下面详细介绍这些方法及其使用。

1、size() - 获取元素数量

size()函数返回当前list容器中的元素个数。

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);cout << "当前list中的元素数量: " << lt.size() << endl; // 输出: 4return 0;
}

2、resize() - 调整容器大小

resize()函数用于改变list的大小,有两种情况:

  1. 当新大小大于当前size时,将size扩大到该值,新增元素为第二个参数值(若未提供则使用默认值0)

  2. 当新大小小于当前size时,将size缩小到该值,多余元素被删除

#include <iostream>
#include <list>
using namespace std;void printList(const list<int>& lt) {for (auto e : lt) {cout << e << " ";}cout << endl;
}int main()
{// 初始化list,包含5个值为3的元素list<int> lt(5, 3);printList(lt); // 输出: 3 3 3 3 3// 扩大list大小为7,新增元素值为6lt.resize(7, 6);printList(lt); // 输出: 3 3 3 3 3 6 6// 缩小list大小为2lt.resize(2);printList(lt); // 输出: 3 3// 扩大list但不指定新增元素值,使用int默认值0lt.resize(5);printList(lt); // 输出: 3 3 0 0 0return 0;
}

3、empty() - 检查容器是否为空

empty()函数返回一个布尔值,表示容器是否为空(size为0)。

#include <iostream>
#include <list>
using namespace std;int main()
{list<int> lt;cout << "list是否为空? " << (lt.empty() ? "是" : "否") << endl; // 输出: 是lt.push_back(10);cout << "list是否为空? " << (lt.empty() ? "是" : "否") << endl; // 输出: 否return 0;
}

4、clear() - 清空容器

clear()函数删除容器中的所有元素,使size变为0。

#include <iostream>
#include <list>
using namespace std;void printListInfo(const list<int>& lt) {cout << "元素: ";for (auto e : lt) {cout << e << " ";}cout << "\n大小: " << lt.size() << endl;
}int main()
{list<int> lt(5, 2); // 5个值为2的元素printListInfo(lt);/* 输出:元素: 2 2 2 2 2 大小: 5*/lt.clear(); // 清空容器printListInfo(lt);/* 输出:元素: 大小: 0*/return 0;
}

总结

方法功能描述时间复杂度
size()返回容器中的元素数量O(1)
resize(n)调整容器大小为nO(n-size)
empty()检查容器是否为空O(1)
clear()删除所有元素,size变为0O(n)

        这些方法为list容器提供了灵活的大小控制能力,可以根据需要动态调整容器大小或查询容器状态。


七、list容器操作函数

        list是C++标准模板库(STL)中的一个双向链表容器,提供了多种操作函数来高效地管理数据。下面详细介绍list的各种常用操作函数。

1、sort函数

sort函数用于对list容器中的元素进行排序,默认按升序排列。

#include <iostream>
#include <list>
using namespace std;int main() {list<int> lt = {4, 7, 5, 9, 6, 0, 3};cout << "排序前: ";for (auto e : lt) cout << e << " "; // 输出: 4 7 5 9 6 0 3cout << endl;lt.sort(); // 默认升序排序cout << "排序后: ";for (auto e : lt) cout << e << " "; // 输出: 0 3 4 5 6 7 9cout << endl;return 0;
}

2、splice函数

splice函数用于两个list容器之间的拼接,有三种使用方式:

  1. 将整个容器拼接到另一个容器的指定位置

  2. 将容器中的某个元素拼接到另一个容器的指定位置

  3. 将容器指定区间的元素拼接到另一个容器的指定位置

#include <iostream>
#include <list>
using namespace std;int main() {// 1. 整个容器拼接list<int> lt1(4, 2);list<int> lt2(4, 6);lt1.splice(lt1.begin(), lt2); // 将lt2拼接到lt1开头cout << "整个容器拼接结果: ";for (auto e : lt1) cout << e << " "; // 输出: 6 6 6 6 2 2 2 2cout << endl;// 2. 单个元素拼接list<int> lt3(4, 2);list<int> lt4(4, 6);lt3.splice(lt3.begin(), lt4, lt4.begin()); // 将lt4的第一个元素拼接到lt3开头cout << "单个元素拼接结果: ";for (auto e : lt3) cout << e << " "; // 输出: 6 2 2 2 2cout << endl;// 3. 区间元素拼接list<int> lt5(4, 2);list<int> lt6(4, 6);lt5.splice(lt5.begin(), lt6, lt6.begin(), lt6.end()); // 将lt6的全部元素拼接到lt5开头cout << "区间元素拼接结果: ";for (auto e : lt5) cout << e << " "; // 输出: 6 6 6 6 2 2 2 2cout << endl;return 0;
}

注意容器当中被拼接到另一个容器的数据在原容器当中就不存在了。(实际上就是将链表当中的指定结点拼接到了另一个容器当中)

3、remove和remove_if函数

remove函数删除容器中所有等于指定值的元素;remove_if函数删除满足特定条件的元素。

#include <iostream>
#include <list>
using namespace std;bool is_single_digit(const int& val) {return val < 10;
}int main() {// remove示例list<int> lt = {1, 4, 3, 3, 2, 2, 3};cout << "remove前: ";for (auto e : lt) cout << e << " "; // 输出: 1 4 3 3 2 2 3cout << endl;lt.remove(3); // 删除所有值为3的元素cout << "remove后: ";for (auto e : lt) cout << e << " "; // 输出: 1 4 2 2cout << endl;// remove_if示例list<int> lt2 = {10, 4, 7, 18, 2, 5, 9};cout << "remove_if前: ";for (auto e : lt2) cout << e << " "; // 输出: 10 4 7 18 2 5 9cout << endl;lt2.remove_if(is_single_digit); // 删除所有小于10的元素cout << "remove_if后: ";for (auto e : lt2) cout << e << " "; // 输出: 10 18cout << endl;return 0;
}

4、unique函数

unique函数删除容器中连续的重复元素。通常需要先排序才能实现完全去重。

#include <iostream>
#include <list>
using namespace std;int main() {list<int> lt = {1, 4, 3, 3, 2, 2, 3};cout << "原始数据: ";for (auto e : lt) cout << e << " "; // 输出: 1 4 3 3 2 2 3cout << endl;lt.sort(); // 先排序lt.unique(); // 再去重cout << "去重后: ";for (auto e : lt) cout << e << " "; // 输出: 1 2 3 4cout << endl;return 0;
}

5、merge函数

merge函数用于合并两个已排序的list容器,合并后仍然保持有序。(类似于归并排序)

#include <iostream>
#include <list>
using namespace std;int main() {list<int> lt1 = {3, 8, 1};list<int> lt2 = {6, 2, 9, 5};lt1.sort(); // 排序lt1: 1, 3, 8lt2.sort(); // 排序lt2: 2, 5, 6, 9lt1.merge(lt2); // 合并lt2到lt1cout << "合并后结果: ";for (auto e : lt1) cout << e << " "; // 输出: 1 2 3 5 6 8 9cout << endl;return 0;
}

6、reverse函数

reverse函数用于反转容器中元素的顺序。

#include <iostream>
#include <list>
using namespace std;int main() {list<int> lt = {1, 2, 3, 4, 5};cout << "反转前: ";for (auto e : lt) cout << e << " "; // 输出: 1 2 3 4 5cout << endl;lt.reverse(); // 反转元素顺序cout << "反转后: ";for (auto e : lt) cout << e << " "; // 输出: 5 4 3 2 1cout << endl;return 0;
}

7、assign函数

assign函数用于替换容器中的内容,有两种方式:

  1. 用n个值为val的元素替换

  2. 用迭代器区间内的元素替换

#include <iostream>
#include <string>
#include <list>
using namespace std;int main() {// 方式1: 用n个值替换list<char> lt(3, 'a');lt.assign(3, 'b'); // 用3个'b'替换原有内容cout << "assign方式1: ";for (auto e : lt) cout << e << " "; // 输出: b b bcout << endl;// 方式2: 用迭代器区间替换string s("hello world");lt.assign(s.begin(), s.end()); // 用字符串内容替换cout << "assign方式2: ";for (auto e : lt) cout << e << " "; // 输出: h e l l o   w o r l dcout << endl;return 0;
}

8、swap函数

swap函数用于交换两个容器的内容。

#include <iostream>
#include <list>
using namespace std;int main() {list<int> lt1(4, 2);list<int> lt2(4, 6);lt1.swap(lt2); // 交换两个容器的内容cout << "lt1交换后: ";for (auto e : lt1) cout << e << " "; // 输出: 6 6 6 6cout << endl;cout << "lt2交换后: ";for (auto e : lt2) cout << e << " "; // 输出: 2 2 2 2cout << endl;return 0;
}


八、List迭代器失效问题

1、迭代器失效的概念

        迭代器可以简单理解为一种智能指针,它提供了访问容器元素的统一接口。当迭代器指向的容器元素变得无效时,就发生了迭代器失效。对于list而言,迭代器失效特指迭代器所指向的节点被删除,导致该迭代器无法继续使用的情况。

2、List迭代器失效的特点

由于list的底层实现是带头节点的双向循环链表,它具有以下特性:

  1. 插入操作:不会导致任何迭代器失效,因为新节点的加入不会影响已有节点的内存地址

  2. 删除操作:只会使指向被删除节点的迭代器失效,其他迭代器不受影响

3、错误示例分析

void TestListIterator1() {int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()) {// 错误:erase()后it已失效,再执行++it是未定义行为l.erase(it);  ++it;}
}

上述代码的问题在于:

  1. erase(it)调用后,it指向的节点已被删除

  2. 对已失效的迭代器执行++it操作会导致未定义行为

  3. 程序可能会崩溃或产生不可预测的结果

4、正确解决方案

方案1:利用后置++的特性

void TestListIterator() {int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()) {l.erase(it++);  // 先传递it的副本,再递增it}
}
erase(it++) 的执行流程
  1. it++ 的语义

    • it++ 是后置递增操作,它的行为是:

      • 先返回 it 的当前值(副本)

      • 然后递增 it 本身(指向下一个元素)

    • 所以 erase(it++) 实际上是:

      • 先传递 it 的原始值(副本)给 erase

      • 然后 it 自身递增,指向下一个元素

  2. erase 的作用

    • erase 删除的是传入的迭代器指向的节点,也就是 it 的副本指向的元素

    • 由于 it 自身已经被递增,所以它现在指向的是下一个有效节点,而不是被删除的节点

具体例子

假设初始 list 是 {1, 2, 3}it 初始指向 1

  1. 第一次循环

    • erase(it++)

      • 传递给 erase 的是 it 的副本(指向 1

      • it 自身递增,现在指向 2

      • erase 删除 1,但 it 已经指向 2,所以不会失效

    • 现在 list 是 {2, 3}it 指向 2

  2. 第二次循环

    • erase(it++)

      • 传递给 erase 的是 it 的副本(指向 2

      • it 自身递增,现在指向 3

      • erase 删除 2,但 it 已经指向 3,所以不会失效

    • 现在 list 是 {3}it 指向 3

  3. 第三次循环

    • erase(it++)

      • 传递给 erase 的是 it 的副本(指向 3

      • it 自身递增,现在指向 end()

      • erase 删除 3it 已经指向 end(),循环终止

关键点
  • erase 删除的是副本指向的节点,不是 it 当前指向的节点

  • it 自身在 erase 之前就已经递增,所以不会失效

  • 这种方式避免了 erase 后 it 变成野指针的问题

方案2:使用erase的返回值

void TestListIterator() {int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()) {it = l.erase(it);  // erase返回被删除元素的下一个有效迭代器}
}
  • erase 会返回被删除元素的下一个有效迭代器

  • 这样代码更易读,且适用于所有标准库容器(如 vectordeque 等)

两种解决方案都能正确处理list的迭代器失效问题,推荐使用第二种方案,因为:

  1. 代码意图更明确

  2. 不依赖于后置++的求值顺序

  3. 与其他STL容器的erase操作保持一致性

http://www.dtcms.com/a/334408.html

相关文章:

  • VS Code配置MinGW64编译GLPK(GNU Linear Programming Kit)开源库
  • 实现Android图片手势缩放功能的完整自定义View方案,结合了多种手势交互功能
  • 纸板制造制胶工艺学习记录4
  • Redis集群设计实战:从90%缓存命中率看高并发系统优化
  • Windows常见文件夹cache的作用还有其他缓存类型文件夹的作用
  • backward怎么计算的是torch.tensor(2.0, requires_grad=True)变量的梯度
  • 【论文阅读】Multimodal Graph Contrastive Learning for Multimedia-based Recommendation
  • Linux 下 安装 matlab 2025A
  • 机器学习——CountVectorizer将文本集合转换为 基于词频的特征矩阵
  • 软件的终极:为70亿人编写70亿个不同的软件
  • C++面试题及详细答案100道( 31-40 )
  • SysTick寄存器(嘀嗒定时器实现延时)
  • cPanel Python 应用部署流程
  • 记录一下第一次patch kernel的经历
  • CSV 生成 Gantt 甘特图
  • 2^{-53} 单位舍入误差、机器精度、舍入的最大相对误差界限
  • 【QGIS数据篇】QGIS 3.40 栅格计算器经典实用公式全集
  • 高并发场景下如何避免重复支付
  • 17.3 全选购物车
  • 双椒派E2000D开发板LED驱动开发实战指南
  • 线程回收与线程间通信
  • [Python 基础课程]抽象类
  • 强化学习入门教程(附学习文档)
  • (第十七期)HTML图像标签详解:从入门到精通
  • 创新词汇表设计:UniVoc - 中英文混合处理的新方案
  • 安卓11 12系统修改定制化_____列举与安卓 9、10 系统在定制化方面的差异与权限不同
  • 数学建模Topsis法笔记
  • 非功能性需求设计:可解释性、鲁棒性、隐私合规
  • 【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
  • 启发式合并 + 莫队 恋恋的心跳大冒险