
前言
大家好!今天我们来深入学习《C++ 程序设计》第 10 章的内容 ——泛型程序设计与 C++ 标准模板库 (STL)。STL 是 C++ 中最强大的特性之一,它提供了一套丰富的模板类和函数,帮助我们高效地进行程序设计。本章将从泛型编程的基本概念出发,逐步讲解 STL 的核心组件:迭代器、容器、函数对象和算法,最后通过综合实例展示 STL 的实际应用。
泛型程序设计 (Generic Programming) 是一种独立于特定数据类型的编程范式,它专注于算法和数据结构的逻辑结构,而将具体的数据类型作为参数传入。这种思想的核心是代码复用和算法通用化。
泛型编程的优势:
C++ 标准模板库 (STL) 是泛型编程思想的典型实现,它主要包含以下四大核心组件:

STL 组件关系:算法通过迭代器操作容器中的数据,函数对象可以作为算法的参数定制算法行为,形成了 "容器存储数据,迭代器连接容器与算法,算法实现操作逻辑,函数对象扩展算法功能" 的完整体系。
迭代器 (Iterator) 是连接容器和算法的桥梁,它提供了一种统一的方式来访问容器中的元素,而无需暴露容器的内部实现细节。
输入流迭代器 (istream_iterator) 和输出流迭代器 (ostream_iterator) 是特殊的迭代器,用于将流作为容器处理。
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
int main() {
// 输入流迭代器:从标准输入读取整数
std::cout << "请输入一些整数(按Ctrl+Z结束):" << std::endl;
std::istream_iterator<int> in_iter(std::cin);
std::istream_iterator<int> end_of_stream; // 流结束迭代器
// 输出流迭代器:将数据输出到标准输出,每个元素后加空格
std::ostream_iterator<int> out_iter(std::cout, " ");
// 使用算法将输入流数据复制到输出流
std::copy(in_iter, end_of_stream, out_iter);
std::cout << std::endl;
return 0;
}
STL 将迭代器分为 5 类,每类支持不同的操作集,形成了一个继承关系:

istream_iteratorostream_iteratorforward_list的迭代器list、set、map的迭代器vector、deque的迭代器 STL 中算法通常使用半开区间[first, last)来表示元素范围,即包含first指向的元素,但不包含last指向的元素。这种表示方式有以下优势:
first == last[first, mid)和[mid, last)无重叠且覆盖原区间#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 区间[begin, end)包含所有元素
std::cout << "所有元素: ";
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 区间[begin, begin+3)包含前3个元素
std::cout << "前3个元素: ";
for (auto it = vec.begin(); it != vec.begin() + 3; ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
STL 提供了三个常用的迭代器辅助函数:
advance(it, n):将迭代器 it 前进 n 个位置distance(first, last):计算两个迭代器之间的距离iter_swap(it1, it2):交换两个迭代器指向的元素#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> vec = {10, 20, 30, 40, 50};
auto it = vec.begin();
// 前进2个位置
std::advance(it, 2);
std::cout << "前进2个位置后的值: " << *it << std::endl; // 输出30
// 计算距离
int dist = std::distance(vec.begin(), vec.end());
std::cout << "容器长度: " << dist << std::endl; // 输出5
// 交换元素
std::iter_swap(vec.begin(), vec.end() - 1);
std::cout << "交换首尾元素后: ";
for (auto num : vec) {
std::cout << num << " "; // 输出50 20 30 40 10
}
std::cout << std::endl;
return 0;
}
容器 (Container) 是 STL 中用于存储数据的类模板,提供了管理对象集合的标准化接口。
容器的基本功能:
容器的分类:
vector、listset、mapstack、queue所有顺序容器都提供统一的接口,包括:
begin()/end():获取迭代器push_back():在尾部插入元素size():获取元素个数empty():判断是否为空clear():清空容器insert():插入元素erase():删除元素STL 提供 5 种顺序容器,各有不同的特性和适用场景:
容器类型 | 内部实现 | 随机访问 | 尾部插入 / 删除 | 中间插入 / 删除 | 内存连续性 |
|---|---|---|---|---|---|
vector | 动态数组 | 支持 (O (1)) | 快 (amortized O (1) ) | 慢 (O (n)) | 连续 |
deque | 分段数组 | 支持 (O (1)) | 快 (O (1)) | 慢 (O (n)) | 不连续 |
list | 双向链表 | 不支持 | 快 (O (1)) | 快 (O (1)) | 不连续 |
forward_list | 单向链表 | 不支持 | 不支持 | 快 (O (1)) | 不连续 |
array | 静态数组 | 支持 (O (1)) | 不支持 | 不支持 | 连续 |
#include <vector>
#include <deque>
#include <list>
#include <array>
#include <forward_list>
#include <iostream>
int main() {
// vector示例
std::vector<int> vec = {1, 2, 3};
vec.push_back(4); // 尾部插入
std::cout << "vector: ";
for (int v : vec) std::cout << v << " "; // 1 2 3 4
std::cout << std::endl;
// deque示例
std::deque<int> dq = {10, 20};
dq.push_front(5); // 头部插入
dq.push_back(30); // 尾部插入
std::cout << "deque: ";
for (int d : dq) std::cout << d << " "; // 5 10 20 30
std::cout << std::endl;
// list示例
std::list<int> lst = {100, 200};
lst.insert(lst.begin(), 50); // 头部插入
lst.insert(++lst.begin(), 75); // 中间插入
std::cout << "list: ";
for (int l : lst) std::cout << l << " "; // 50 75 100 200
std::cout << std::endl;
// array示例(固定大小)
std::array<int, 3> arr = {1, 2, 3};
arr[1] = 5; // 修改元素
std::cout << "array: ";
for (int a : arr) std::cout << a << " "; // 1 5 3
std::cout << std::endl;
return 0;
}
插入迭代器是一种特殊的迭代器,用于将元素插入容器的特定位置,包括:
back_inserter:在容器尾部插入front_inserter:在容器头部插入(仅支持deque、list)inserter:在指定位置插入#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3};
std::list<int> lst;
// 使用back_inserter在尾部插入
std::copy(vec.begin(), vec.end(), std::back_inserter(lst));
std::cout << "list after back_inserter: ";
for (int l : lst) std::cout << l << " "; // 1 2 3
std::cout << std::endl;
// 使用front_inserter在头部插入
std::list<int> lst2;
std::copy(vec.begin(), vec.end(), std::front_inserter(lst2));
std::cout << "list after front_inserter: ";
for (int l : lst2) std::cout << l << " "; // 3 2 1
std::cout << std::endl;
// 使用inserter在指定位置插入
std::vector<int> vec2 = {10, 20, 30};
std::copy(vec.begin(), vec.end(), std::inserter(vec2, vec2.begin() + 1));
std::cout << "vector after inserter: ";
for (int v : vec2) std::cout << v << " "; // 10 1 2 3 20 30
std::cout << std::endl;
return 0;
}
容器适配器对现有容器进行包装,提供特定的数据结构接口:
stack:栈,后进先出 (LIFO),默认基于deque实现queue:队列,先进先出 (FIFO),默认基于deque实现priority_queue:优先队列,默认基于vector实现,每次出队最大元素#include <stack>
#include <queue>
#include <iostream>
int main() {
// 栈示例
std::stack<int> st;
st.push(10);
st.push(20);
st.push(30);
std::cout << "stack elements: ";
while (!st.empty()) {
std::cout << st.top() << " "; // 30 20 10
st.pop();
}
std::cout << std::endl;
// 队列示例
std::queue<int> q;
q.push(10);
q.push(20);
q.push(30);
std::cout << "queue elements: ";
while (!q.empty()) {
std::cout << q.front() << " "; // 10 20 30
q.pop();
}
std::cout << std::endl;
// 优先队列示例
std::priority_queue<int> pq;
pq.push(30);
pq.push(10);
pq.push(20);
std::cout << "priority_queue elements: ";
while (!pq.empty()) {
std::cout << pq.top() << " "; // 30 20 10
pq.pop();
}
std::cout << std::endl;
return 0;
}
关联容器存储的是键值对(key-value pair),元素按关键字自动排序,支持快速查找 (O (log n))。关联容器的基本功能包括:
insert():插入键值对erase():删除键值对find():按关键字查找count():统计关键字出现次数size()/empty():容器大小相关操作 set是存储唯一关键字的集合,元素既是关键字也是值,默认按升序排列:
#include <set>
#include <iostream>
int main() {
// 创建set并插入元素
std::set<int> s;
s.insert(30);
s.insert(10);
s.insert(20);
s.insert(10); // 重复元素,不会被插入
// 遍历set(自动排序)
std::cout << "set elements: ";
for (int num : s) {
std::cout << num << " "; // 10 20 30
}
std::cout << std::endl;
// 查找元素
auto it = s.find(20);
if (it != s.end()) {
std::cout << "找到元素: " << *it << std::endl; // 找到元素: 20
}
// 删除元素
s.erase(20);
std::cout << "删除20后: ";
for (int num : s) {
std::cout << num << " "; // 10 30
}
std::cout << std::endl;
return 0;
}
map存储键值对,每个关键字唯一,通过[]或at()可以快速访问值:
#include <map>
#include <string>
#include <iostream>
int main() {
// 创建map存储姓名和年龄
std::map<std::string, int> person_ages;
// 插入元素
person_ages["Alice"] = 25;
person_ages["Bob"] = 30;
person_ages.insert({"Charlie", 35});
// 遍历map
std::cout << "map elements: " << std::endl;
for (const auto& pair : person_ages) {
std::cout << pair.first << ": " << pair.second << "岁" << std::endl;
}
// 输出:
// Alice: 25岁
// Bob: 30岁
// Charlie: 35岁
// 访问元素
std::cout << "Alice的年龄: " << person_ages["Alice"] << std::endl; // 25
// 查找元素
auto it = person_ages.find("Bob");
if (it != person_ages.end()) {
std::cout << "找到Bob: " << it->second << "岁" << std::endl; // 30
}
return 0;
}
multiset:允许存储重复关键字的集合multimap:允许存储重复关键字的映射#include <iostream>
#include <set> // 包含multiset所需的头文件
#include <map> // 包含multimap所需的头文件
#include <string>
int main() {
// multiset示例:允许存储重复元素的集合
std::multiset<int> ms;
ms.insert(20);
ms.insert(10);
ms.insert(20); // 允许插入重复元素
ms.insert(30);
std::cout << "multiset elements: ";
// 元素会自动排序
for (int num : ms) {
std::cout << num << " "; // 输出:10 20 20 30
}
std::cout << std::endl;
// 统计元素出现的次数
std::cout << "数字20出现的次数: " << ms.count(20) << std::endl; // 输出:2
// multimap示例:允许键重复的映射
std::multimap<std::string, std::string> courses;
courses.insert({"Math", "Alice"});
courses.insert({"Math", "Bob"}); // 允许相同的键
courses.insert({"Physics", "Charlie"});
courses.insert({"Math", "David"}); // 允许相同的键
std::cout << "Math课程的学生: ";
// 查找所有键为"Math"的元素
auto range = courses.equal_range("Math");
for (auto it = range.first; it != range.second; ++it) {
std::cout << it->second << " "; // 输出:Alice Bob David
}
std::cout << std::endl;
return 0;
}
C++11 引入了无序容器,基于哈希表实现,包括unordered_set、unordered_map、unordered_multiset、unordered_multimap。特点是:
#include <unordered_set>
#include <unordered_map>
#include <iostream>
int main() {
// unordered_set示例
std::unordered_set<std::string> us;
us.insert("apple");
us.insert("banana");
us.insert("cherry");
std::cout << "unordered_set elements: ";
for (const auto& fruit : us) {
std::cout << fruit << " "; // 顺序不确定
}
std::cout << std::endl;
// unordered_map示例
std::unordered_map<int, std::string> um;
um[1] = "one";
um[2] = "two";
um[3] = "three";
std::cout << "unordered_map elements: ";
for (const auto& pair : um) {
std::cout << pair.first << ":" << pair.second << " "; // 顺序不确定
}
std::cout << std::endl;
return 0;
}
函数对象 (Function Object) 是重载了函数调用运算符() 的类对象,它可以像函数一样被调用。相比普通函数,函数对象可以携带状态。
STL 提供了一些预定义函数对象,如:
std::plus:加法std::minus:减法std::greater:大于比较#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
// 自定义函数对象:计算累加和
class Adder {
private:
int sum;
public:
Adder() : sum(0) {}
// 重载函数调用运算符
void operator()(int num) {
sum += num;
}
int get_sum() const {
return sum;
}
};
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用自定义函数对象
Adder adder;
adder = std::for_each(vec.begin(), vec.end(), adder);
std::cout << "总和: " << adder.get_sum() << std::endl; // 15
// 使用STL预定义函数对象
std::vector<int> vec2 = {3, 1, 4, 1, 5};
// 使用greater排序,实现降序
std::sort(vec2.begin(), vec2.end(), std::greater<int>());
std::cout << "降序排列: ";
for (int num : vec2) {
std::cout << num << " "; // 5 4 3 1 1
}
std::cout << std::endl;
return 0;
}
C++11 引入了 lambda 表达式,允许在代码中定义匿名函数对象,语法为:
[capture](parameters) -> return_type { body }#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 使用lambda表达式过滤偶数
std::cout << "偶数: ";
std::for_each(vec.begin(), vec.end(), [](int num) {
if (num % 2 == 0) {
std::cout << num << " "; // 2 4 6 8 10
}
});
std::cout << std::endl;
// 使用lambda表达式捕获外部变量
int threshold = 5;
std::cout << "大于" << threshold << "的数: ";
std::for_each(vec.begin(), vec.end(), [threshold](int num) {
if (num > threshold) {
std::cout << num << " "; // 6 7 8 9 10
}
});
std::cout << std::endl;
// 使用lambda表达式修改外部变量(需要使用引用捕获)
int sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int num) {
sum += num;
});
std::cout << "总和: " << sum << std::endl; // 55
return 0;
}
std::bind可以将函数或函数对象与部分参数绑定,生成新的函数对象:
#include <functional>
#include <iostream>
#include <vector> // 新增:包含vector头文件
// 普通函数
int add(int a, int b, int c) {
return a + b + c;
}
int main() {
// 绑定add函数的前两个参数为10和20
auto add10_20 = std::bind(add, 10, 20, std::placeholders::_1);
std::cout << "10 + 20 + 30 = " << add10_20(30) << std::endl; // 60
// 绑定add函数的第一个和第三个参数
auto add_x_5 = std::bind(add, std::placeholders::_1, 5, std::placeholders::_2);
std::cout << "20 + 5 + 35 = " << add_x_5(20, 35) << std::endl; // 60
// 绑定成员函数
std::vector<int> vec = {1, 2, 3};
// 绑定vector的size()成员函数
auto print_size = std::bind(&std::vector<int>::size, std::placeholders::_1);
std::cout << "vector大小: " << print_size(vec) << std::endl; // 3
return 0;
}
STL 算法是一系列模板函数,用于操作容器中的元素,主要分为:
算法通常通过迭代器操作容器,不直接依赖容器类型,具有高度通用性。
不可变序列算法用于查询或分析元素,不修改容器内容:
find():查找元素count():统计元素出现次数for_each():遍历元素equal():比较两个区间是否相等max_element()/min_element():查找最大 / 小元素#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6};
// 查找元素5
auto it = std::find(vec.begin(), vec.end(), 5);
if (it != vec.end()) {
std::cout << "找到元素5,位置: " << it - vec.begin() << std::endl; // 4
}
// 统计元素1出现的次数
int count = std::count(vec.begin(), vec.end(), 1);
std::cout << "元素1出现的次数: " << count << std::endl; // 2
// 查找最大值和最小值
auto max_it = std::max_element(vec.begin(), vec.end());
auto min_it = std::min_element(vec.begin(), vec.end());
std::cout << "最大值: " << *max_it << ", 最小值: " << *min_it << std::endl; // 9, 1
return 0;
}
可变序列算法会修改容器中的元素:
copy():复制元素transform():转换元素replace():替换元素fill():填充元素remove():删除元素#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
std::vector<int> vec2(5);
// 复制元素
std::copy(vec.begin(), vec.end(), vec2.begin());
std::cout << "复制后的vec2: ";
for (int num : vec2) std::cout << num << " "; // 1 2 3 4 5
std::cout << std::endl;
// 转换元素(每个元素乘以2)
std::transform(vec.begin(), vec.end(), vec.begin(), [](int x) { return x * 2; });
std::cout << "转换后的vec: ";
for (int num : vec) std::cout << num << " "; // 2 4 6 8 10
std::cout << std::endl;
// 替换元素(将4替换为0)
std::replace(vec.begin(), vec.end(), 4, 0);
std::cout << "替换后的vec: ";
for (int num : vec) std::cout << num << " "; // 2 0 6 8 10
std::cout << std::endl;
return 0;
}
sort():排序元素stable_sort():稳定排序binary_search():二分查找lower_bound()/upper_bound():查找下界 / 上界merge():合并两个有序区间#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6};
// 排序
std::sort(vec.begin(), vec.end());
std::cout << "排序后: ";
for (int num : vec) std::cout << num << " "; // 1 1 2 3 4 5 6 9
std::cout << std::endl;
// 二分查找
bool found = std::binary_search(vec.begin(), vec.end(), 5);
std::cout << "是否找到5: " << (found ? "是" : "否") << std::endl; // 是
// 查找下界和上界
auto lower = std::lower_bound(vec.begin(), vec.end(), 1);
auto upper = std::upper_bound(vec.begin(), vec.end(), 1);
std::cout << "元素1的范围: [" << lower - vec.begin() << ", "
<< upper - vec.begin() << ")" << std::endl; // [0, 2)
// 合并两个有序向量
std::vector<int> vec1 = {1, 3, 5};
std::vector<int> vec2 = {2, 4, 6};
std::vector<int> merged(6);
std::merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), merged.begin());
std::cout << "合并后: ";
for (int num : merged) std::cout << num << " "; // 1 2 3 4 5 6
std::cout << std::endl;
return 0;
}
数值算法用于数值计算,定义在<numeric>头文件中:
accumulate():累加元素inner_product():计算内积partial_sum():计算前缀和iota():生成连续值#include <vector>
#include <numeric>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 累加元素
int sum = std::accumulate(vec.begin(), vec.end(), 0);
std::cout << "总和: " << sum << std::endl; // 15
// 累加元素(乘以2)
int sum2 = std::accumulate(vec.begin(), vec.end(), 0,
[](int total, int num) { return total + num * 2; });
std::cout << "每个元素乘2后总和: " << sum2 << std::endl; // 30
// 计算内积
std::vector<int> vec2 = {10, 20, 30, 40, 50};
int dot_product = std::inner_product(vec.begin(), vec.end(), vec2.begin(), 0);
std::cout << "内积: " << dot_product << std::endl; // 1*10 + 2*20 + ... +5*50 = 550
// 计算前缀和
std::vector<int> prefix_sums(vec.size());
std::partial_sum(vec.begin(), vec.end(), prefix_sums.begin());
std::cout << "前缀和: ";
for (int num : prefix_sums) std::cout << num << " "; // 1 3 6 10 15
std::cout << std::endl;
return 0;
}
下面我们使用 STL 改进一个个人银行账户管理程序,使用map存储账户信息,使用算法进行账户查询、排序等操作:
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <numeric>
#include <iomanip>
#include <iterator> // 新增:包含back_inserter所需的头文件
// 账户类
class Account {
private:
std::string account_id; // 账户ID
std::string name; // 账户名
double balance; // 余额
public:
// 构造函数
Account(std::string id, std::string n, double b)
: account_id(std::move(id)), name(std::move(n)), balance(b) {}
// 获取账户ID
const std::string& get_id() const { return account_id; }
// 获取账户名
const std::string& get_name() const { return name; }
// 获取余额
double get_balance() const { return balance; }
// 存款
void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
// 取款
bool withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
return true;
}
return false;
}
// 显示账户信息
void display() const {
std::cout << std::left << std::setw(10) << account_id
<< std::setw(15) << name
<< std::fixed << std::setprecision(2) << balance << std::endl;
}
};
// 银行类,使用STL容器管理账户
class Bank {
private:
// 使用map存储账户,key为账户ID,value为Account对象
std::map<std::string, Account> accounts;
public:
// 添加账户
void add_account(const Account& acc) {
accounts.insert({acc.get_id(), acc});
}
// 查找账户
Account* find_account(const std::string& id) {
auto it = accounts.find(id);
if (it != accounts.end()) {
return &(it->second);
}
return nullptr;
}
// 显示所有账户
void display_all() const {
std::cout << std::left << std::setw(10) << "账户ID"
<< std::setw(15) << "账户名"
<< "余额" << std::endl;
std::cout << "-----------------------------------------" << std::endl;
for (const auto& pair : accounts) {
pair.second.display();
}
}
// 获取所有账户余额总和
double get_total_balance() const {
// 使用accumulate算法计算总余额
return std::accumulate(accounts.begin(), accounts.end(), 0.0,
[](double total, const std::pair<std::string, Account>& pair) {
return total + pair.second.get_balance();
});
}
// 获取余额大于指定值的账户
std::vector<Account> get_high_balance_accounts(double threshold) const {
std::vector<Account> result;
// 使用for_each替代copy_if,手动处理元素提取
std::for_each(accounts.begin(), accounts.end(),
[threshold, &result](const std::pair<std::string, Account>& pair) {
if (pair.second.get_balance() > threshold) {
result.push_back(pair.second);
}
});
return result;
}
// 按余额排序账户
std::vector<Account> get_sorted_by_balance() const {
std::vector<Account> result;
// 复制所有账户到vector
for (const auto& pair : accounts) {
result.push_back(pair.second);
}
// 使用sort算法按余额排序
std::sort(result.begin(), result.end(),
[](const Account& a, const Account& b) {
return a.get_balance() < b.get_balance();
});
return result;
}
};
int main() {
// 创建银行对象
Bank bank;
// 添加账户
bank.add_account(Account("1001", "Alice", 1000.50));
bank.add_account(Account("1002", "Bob", 2500.75));
bank.add_account(Account("1003", "Charlie", 800.00));
bank.add_account(Account("1004", "David", 5000.00));
// 显示所有账户
std::cout << "所有账户信息:" << std::endl;
bank.display_all();
std::cout << std::endl;
// 显示总余额
std::cout << "所有账户总余额: " << std::fixed << std::setprecision(2)
<< bank.get_total_balance() << std::endl << std::endl;
// 查找账户并操作
Account* alice = bank.find_account("1001");
if (alice) {
std::cout << "找到Alice的账户,存款前余额: " << alice->get_balance() << std::endl;
alice->deposit(500);
std::cout << "存款500后余额: " << alice->get_balance() << std::endl << std::endl;
}
// 查找高余额账户
double threshold = 2000.0;
std::vector<Account> high_balance = bank.get_high_balance_accounts(threshold);
std::cout << "余额大于" << threshold << "的账户:" << std::endl;
for (const auto& acc : high_balance) {
acc.display();
}
std::cout << std::endl;
// 按余额排序账户
std::vector<Account> sorted = bank.get_sorted_by_balance();
std::cout << "按余额排序的账户:" << std::endl;
for (const auto& acc : sorted) {
acc.display();
}
return 0;
}
swap函数用于交换两个对象的值,STL 为容器提供了高效的特化版本:
swap操作通常是常数时间复杂度#include <vector>
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {4, 5, 6, 7};
std::cout << "交换前: " << std::endl;
std::cout << "vec1: ";
for (int num : vec1) std::cout << num << " "; // 1 2 3
std::cout << std::endl;
std::cout << "vec2: ";
for (int num : vec2) std::cout << num << " "; // 4 5 6 7
std::cout << std::endl;
// 交换两个vector
vec1.swap(vec2);
std::cout << "交换后: " << std::endl;
std::cout << "vec1: ";
for (int num : vec1) std::cout << num << " "; // 4 5 6 7
std::cout << std::endl;
std::cout << "vec2: ";
for (int num : vec2) std::cout << num << " "; // 1 2 3
std::cout << std::endl;
return 0;
}
C++11 引入了<type_traits>头文件,提供了编译期类型信息查询和转换的工具:
#include <type_traits>
#include <iostream>
#include <vector>
#include <list>
int main() {
// 检查类型特性
std::cout << "int是否为算术类型: " << std::is_arithmetic<int>::value << std::endl; // 1
std::cout << "int是否为浮点类型: " << std::is_floating_point<int>::value << std::endl; // 0
std::cout << "vector<int>是否为容器: " << std::is_class<std::vector<int>>::value << std::endl; // 1
// 类型转换
using signed_type = std::make_signed<unsigned int>::type;
std::cout << "unsigned int的有符号版本: " << typeid(signed_type).name() << std::endl; // int
return 0;
}
Boost 是一个开源 C++ 库集合,提供了许多 STL 的扩展功能,是 C++ 标准的重要试验场。许多 Boost 库已被纳入 C++ 标准(如智能指针、正则表达式)。
常用 Boost 库:
Boost 的使用示例(假设已安装 Boost 库):
#include <boost/version.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <string>
#ifdef _WIN32
#include <windows.h>
#endif
int main() {
// 设置控制台编码为UTF-8
#ifdef _WIN32
SetConsoleOutputCP(65001);
#endif
// 原有代码
std::cout << "Boost版本: " << BOOST_VERSION / 100000 << "."
<< (BOOST_VERSION / 100) % 1000 << "."
<< BOOST_VERSION % 100 << std::endl;
std::string str = "Hello, Boost!";
boost::algorithm::to_upper(str);
std::cout << "转换为大写: " << str << std::endl;
std::string str2 = " trim this string ";
boost::algorithm::trim(str2);
std::cout << "去除空格后: '" << str2 << "'" << std::endl;
// 添加暂停代码:等待用户按任意键后再退出
std::cout << "\n程序运行完毕,按任意键退出..." << std::endl;
std::cin.get(); // 等待用户输入一个字符
return 0;
}
本章我们系统学习了 C++ 泛型程序设计和标准模板库 (STL) 的核心内容,主要包括:
vector、deque、list等,按插入顺序存储元素set、map等,按关键字排序,支持快速查找stack、queue等,提供特定数据结构接口()的类对象,以及 C++11 的 lambda 表达式,增强算法灵活性STL 是 C++ 编程的重要工具,掌握 STL 可以大幅提高编程效率和代码质量。通过泛型编程思想,我们可以编写更通用、更灵活、更高效的代码。建议多实践、多使用 STL 组件,深入理解其设计思想和实现原理。
希望本章内容对你有所帮助,欢迎在评论区交流学习心得!
代码说明:本文所有代码均基于 C++11 标准编写,可使用 GCC 或 Clang 编译器编译运行(需添加-std=c++11或更高版本选项)。Boost 库示例需要先安装 Boost 库才能编译。