🎒 STL 是 C++ 程序员的"瑞士军刀"——别人还在手写排序、手动管理链表的时候,你已经用一行代码搞定了。本文从 STL 编程思想出发,带你玩转容器、算法和函数对象,让你的代码从"能跑"进化到"优雅"。


📖 文章导航

  • 9.1 STL 编程思想:STL 是什么?为什么它能让代码变优雅?
  • 9.2 STL 容器:顺序容器(vector、list、deque)+ 关联容器(set、map)
  • 9.3 STL 算法:排序、查找、遍历、变换……几十种算法任你挑
  • 9.4 STL 函数对象:让函数也能当"参数"传来传去

9.1 STL 编程思想——把"造轮子"变成"拼乐高"

1.1 什么是 STL?

STL(Standard Template Library,标准模板库)是 C++ 自带的一个超级工具箱。它提供了三大件:

STL 三大支柱
├── 容器(Container)  ← 存数据的"盒子"
├── 算法(Algorithm)   ← 处理数据的"机器"
└── 迭代器(Iterator)  ← 连接容器和算法的"桥梁"

想象你去宜家买家具:

  • 容器就是你买回来的收纳柜(不同形状、不同大小)
  • 算法就是你的组装工具(螺丝刀、扳手、锤子)
  • 迭代器就是你的——把手伸进柜子里取东西

1.2 STL 的核心思想:泛型编程

STL 的精髓在于模板(template)——算法不关心你存的是 intdouble 还是 string,它只关心"你这个容器支持什么操作"。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    // 存 int
    vector<int> nums = {5, 2, 8, 1, 9};
    sort(nums.begin(), nums.end());
    for (int n : nums) cout << n << " ";   // 1 2 5 8 9
    cout << endl;

    // 存 string——同一个 sort 函数,换个容器就能用!
    vector<string> names = {"Charlie", "Alice", "Bob"};
    sort(names.begin(), names.end());
    for (auto& s : names) cout << s << " "; // Alice Bob Charlie
    cout << endl;

    return 0;
}

💡 一句话理解 STL:写一次算法,能用在任何类型的容器上——这就是"泛型编程"的魅力。


9.2 STL 容器——你的数据住哪种"房子"?

STL 容器分为两大门派:顺序容器关联容器

STL 容器
├── 顺序容器:按插入顺序排列,你放哪它就在哪
│   ├── vector   ← 动态数组(最常用!)
│   ├── list     ← 双向链表
│   └── deque    ← 双端队列
│
└── 关联容器:按"键"自动排序,查找飞快
    ├── set      ← 集合(不重复)
    └── map      ← 键值对(字典)

2.1 顺序容器——排队的艺术

2.1.1 vector:动态数组(⭐ 最常用!)

vector 就像一个能自动伸缩的数组。用的时候和普通数组一样方便,但它能在运行时自动扩容。

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 创建 vector
    vector<int> v;           // 空的
    vector<int> v2(5, 10);   // 5 个元素,全是 10:{10,10,10,10,10}
    vector<int> v3 = {1,2,3,4,5};  // 初始化列表

    // 尾部添加
    v.push_back(10);
    v.push_back(20);
    v.push_back(30);
    // v 现在是 {10, 20, 30}

    // 访问元素
    cout << v[0] << endl;     // 10(下标访问,不检查越界)
    cout << v.at(1) << endl;  // 20(at 访问,越界会抛异常)
    cout << v.front() << endl; // 10(第一个元素)
    cout << v.back() << endl;  // 30(最后一个元素)

    // 大小
    cout << "大小: " << v.size() << endl;  // 3

    // 删除尾部
    v.pop_back();
    // v 现在是 {10, 20}

    // 遍历方式一:下标遍历
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    cout << endl;

    // 遍历方式二:范围 for(C++11,推荐!)
    for (int x : v) {
        cout << x << " ";
    }
    cout << endl;

    // 遍历方式三:迭代器
    for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

💡 vector 的使用场景:需要随机访问、尾部增删频繁、不确定数据量大小——90% 的情况用它就对了。

vector 的内存机制:自动扩容

vector<int> v;
for (int i = 0; i < 10; i++) {
    v.push_back(i);
    cout << "size=" << v.size() 
         << " capacity=" << v.capacity() << endl;
}
// size 是实际元素数量,capacity 是已分配的存储空间
// capacity 会按 1, 2, 4, 8, 16... 的规律翻倍增长

⚠️ 性能提示:如果你提前知道大概需要多少元素,用 v.reserve(n) 预分配空间,避免频繁扩容。

2.1.2 list:双向链表

list 就像一条双向通行的链条——在任意位置插入和删除都非常快(O(1)),但不支持随机访问。

#include <iostream>
#include <list>
using namespace std;

int main() {
    list<int> lst = {1, 2, 3, 4, 5};

    // 头部和尾部操作
    lst.push_front(0);    // 头部插入:{0,1,2,3,4,5}
    lst.push_back(6);     // 尾部插入:{0,1,2,3,4,5,6}

    // 删除指定值
    lst.remove(3);         // 删除所有值为 3 的元素:{0,1,2,4,5,6}

    // 排序(list 有自己的 sort 成员函数)
    lst.push_front(9);
    lst.sort();            // {0,1,2,4,5,6,9}

    // 反转
    lst.reverse();         // {9,6,5,4,2,1,0}

    // 遍历
    for (int x : lst) {
        cout << x << " ";
    }
    cout << endl;

    // ⚠️ list 不支持下标访问!
    // lst[0];  // ❌ 编译错误

    return 0;
}

💡 list 的使用场景:频繁在中间插入/删除(比如播放列表、任务队列),不需要随机访问。

2.1.3 deque:双端队列

deque(读作"deck")就像一个两头都能进出的队伍——头尾操作都是 O(1),也支持随机访问。

#include <iostream>
#include <deque>
using namespace std;

int main() {
    deque<int> dq = {3, 4, 5};

    // 两端操作
    dq.push_front(2);   // 头部插入:{2,3,4,5}
    dq.push_front(1);   // 头部插入:{1,2,3,4,5}
    dq.push_back(6);    // 尾部插入:{1,2,3,4,5,6}

    // 随机访问
    cout << dq[0] << endl;  // 1
    cout << dq[5] << endl;  // 6

    // 两端删除
    dq.pop_front();     // {2,3,4,5,6}
    dq.pop_back();      // {2,3,4,5}

    for (int x : dq) cout << x << " ";  // 2 3 4 5
    cout << endl;

    return 0;
}

📊 三种顺序容器对比

特性 vector list deque
底层结构 动态数组 双向链表 分段数组
随机访问 ✅ O(1) ❌ O(n) ✅ O(1)
尾部增删 ✅ O(1) ✅ O(1) ✅ O(1)
头部增删 ❌ O(n) ✅ O(1) ✅ O(1)
中间增删 ❌ O(n) ✅ O(1) ❌ O(n)
内存效率 高(连续) 低(指针开销) 中等
适用场景 通用首选 频繁中间插入删除 两端操作频繁

🎯 选择口诀:不确定用啥就选 vector;需要头尾操作选 deque;需要中间频繁插删选 list


2.2 关联容器——有"索引"的高效查找

2.2.1 set:集合(不重复的有序集合)

set 就像一个自动去重、自动排序的集合——你扔进去的东西,重复的会被忽略,而且自动按从小到大排好。

#include <iostream>
#include <set>
using namespace std;

int main() {
    set<int> s;

    // 插入
    s.insert(5);
    s.insert(2);
    s.insert(8);
    s.insert(2);   // 重复!会被忽略
    s.insert(1);
    // s 自动排序:{1, 2, 5, 8}

    // 遍历(自动有序)
    for (int x : s) {
        cout << x << " ";
    }
    cout << endl;  // 1 2 5 8

    // 查找
    if (s.find(5) != s.end()) {
        cout << "找到了 5!" << endl;
    }

    // 删除
    s.erase(2);  // 删除值为 2 的元素
    // s: {1, 5, 8}

    // 大小
    cout << "元素数量: " << s.size() << endl;  // 3

    // 判断是否存在
    cout << "5 存在吗? " << (s.count(5) ? "是" : "否") << endl;  // 是
    cout << "2 存在吗? " << (s.count(2) ? "是" : "否") << endl;  // 否

    return 0;
}

💡 set 的使用场景:去重、判断元素是否存在、需要自动排序的集合。

multiset:允许重复的 set

multiset<int> ms = {1, 2, 2, 3, 3, 3};
// ms: {1, 2, 2, 3, 3, 3}
cout << ms.count(3) << endl;  // 3(有 3 个 3)

2.2.2 map:键值对(字典)

map 就像一本字典——通过"键"(key)快速查到"值"(value),而且键自动排序。

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main() {
    map<string, int> scores;

    // 插入(三种方式)
    scores["张三"] = 90;           // 下标插入
    scores.insert({"李四", 85});   // insert 插入
    scores.insert(make_pair("王五", 92));

    // 访问
    cout << "张三的成绩: " << scores["张三"] << endl;  // 90

    // 遍历(按键自动排序,中文按拼音排序)
    for (auto& pair : scores) {
        cout << pair.first << ": " << pair.second << endl;
    }

    // 查找
    if (scores.find("李四") != scores.end()) {
        cout << "找到了李四!成绩: " << scores["李四"] << endl;
    }

    // 修改
    scores["张三"] = 95;  // 张三进步了!

    // 删除
    scores.erase("王五");

    // ⚠️ 注意:用 [] 访问不存在的键会自动插入一个默认值!
    cout << scores["赵六"] << endl;  // 输出 0,但"赵六"被自动插入了!
    // 安全的做法是先用 count 或 find 检查

    return 0;
}

💡 map 的使用场景:统计词频、配置管理、任何需要"键→值"映射的场景。

实用案例:统计单词出现次数

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main() {
    string words[] = {"apple", "banana", "apple", "cherry", "banana", "apple"};
    map<string, int> count;

    for (auto& w : words) {
        count[w]++;   // 如果 w 不存在,会自动创建并初始化为 0,然后 ++
    }

    cout << "=== 词频统计 ===" << endl;
    for (auto& p : count) {
        cout << p.first << ": " << p.second << " 次" << endl;
    }
    // apple: 3 次
    // banana: 2 次
    // cherry: 1 次

    return 0;
}

multimap:允许重复键的 map

multimap<string, int> grades;
grades.insert({"张三", 90});
grades.insert({"张三", 95});  // 张三有两门课的成绩
grades.insert({"李四", 88});

// 查找张三的所有成绩
auto range = grades.equal_range("张三");
for (auto it = range.first; it != range.second; ++it) {
    cout << it->first << ": " << it->second << endl;
}
// 张三: 90
// 张三: 95

📊 关联容器对比

特性 set multiset map multimap
存储内容 键值对 键值对
是否允许重复 ❌(键) ✅(键)
是否自动排序 ✅(按键) ✅(按键)
查找效率 O(log n) O(log n) O(log n) O(log n)
典型场景 去重/存在性判断 重复值集合 字典/映射 一对多映射

9.3 STL 算法——几十种现成的"数据处理器"

STL 算法是定义在 <algorithm> 头文件中的函数模板,它们通过迭代器操作容器,不关心容器的具体类型。

3.1 遍历算法:for_each

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void print(int x) {
    cout << x << " ";
}

int main() {
    vector<int> v = {1, 2, 3, 4, 5};

    // for_each:对每个元素执行一个操作
    for_each(v.begin(), v.end(), print);  // 1 2 3 4 5
    cout << endl;

    // 用 Lambda 表达式更简洁(C++11)
    for_each(v.begin(), v.end(), [](int x) {
        cout << x * x << " ";
    });
    cout << endl;  // 1 4 9 16 25

    return 0;
}

3.2 排序算法:sort

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v = {5, 2, 8, 1, 9, 3};

    // 默认升序
    sort(v.begin(), v.end());
    for (int x : v) cout << x << " ";  // 1 2 3 5 8 9
    cout << endl;

    // 降序排序
    sort(v.begin(), v.end(), greater<int>());
    for (int x : v) cout << x << " ";  // 9 8 5 3 2 1
    cout << endl;

    // 自定义排序:按绝对值排序
    vector<int> v2 = {-3, 1, -5, 2, -4};
    sort(v2.begin(), v2.end(), [](int a, int b) {
        return abs(a) < abs(b);  // 按绝对值从小到大
    });
    for (int x : v2) cout << x << " ";  // 1 2 -3 -4 -5
    cout << endl;

    return 0;
}

3.3 查找算法:find、binary_search

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v = {1, 3, 5, 7, 9};

    // find:线性查找(O(n))
    auto it = find(v.begin(), v.end(), 5);
    if (it != v.end()) {
        cout << "找到了 5,位置: " << (it - v.begin()) << endl;  // 位置: 2
    }

    // binary_search:二分查找(O(log n),但容器必须有序!)
    bool found = binary_search(v.begin(), v.end(), 7);
    cout << "7 存在吗? " << (found ? "是" : "否") << endl;  // 是

    // count:统计出现次数
    vector<int> v2 = {1, 2, 2, 3, 2, 4};
    int cnt = count(v2.begin(), v2.end(), 2);
    cout << "2 出现了 " << cnt << " 次" << endl;  // 3 次

    // find_if:按条件查找
    vector<int> v3 = {1, 4, 6, 8, 9};
    auto it2 = find_if(v3.begin(), v3.end(), [](int x) {
        return x % 2 == 0;  // 找第一个偶数
    });
    if (it2 != v3.end()) {
        cout << "第一个偶数: " << *it2 << endl;  // 4
    }

    return 0;
}

3.4 去重算法:unique(搭配 sort 使用)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v = {1, 3, 2, 3, 1, 2, 4, 3};

    // unique 只能去除"相邻"的重复元素,所以要先排序
    sort(v.begin(), v.end());           // {1,1,2,2,3,3,3,4}
    auto last = unique(v.begin(), v.end());  // 去重,返回新末尾
    v.erase(last, v.end());             // 真正删除多余元素

    for (int x : v) cout << x << " ";  // 1 2 3 4
    cout << endl;

    return 0;
}

3.5 变换算法:transform

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> src = {1, 2, 3, 4, 5};
    vector<int> dst(5);

    // 把 src 的每个元素乘以 2,存到 dst
    transform(src.begin(), src.end(), dst.begin(), [](int x) {
        return x * 2;
    });

    for (int x : dst) cout << x << " ";  // 2 4 6 8 10
    cout << endl;

    return 0;
}

3.6 其他常用算法速查

vector<int> v = {5, 2, 8, 1, 9, 3};

// min_element / max_element:最小/最大元素
cout << "最小值: " << *min_element(v.begin(), v.end()) << endl;  // 1
cout << "最大值: " << *max_element(v.begin(), v.end()) << endl;  // 9

// accumulate:求和(需要 #include <numeric>)
#include <numeric>
int sum = accumulate(v.begin(), v.end(), 0);
cout << "总和: " << sum << endl;  // 28

// reverse:反转
reverse(v.begin(), v.end());
for (int x : v) cout << x << " ";  // 3 9 1 8 2 5
cout << endl;

// swap:交换两个变量
int a = 1, b = 2;
swap(a, b);
cout << a << " " << b << endl;  // 2 1

// next_permutation:下一个排列
vector<int> p = {1, 2, 3};
do {
    for (int x : p) cout << x << " ";
    cout << endl;
} while (next_permutation(p.begin(), p.end()));
// 输出:123 132 213 231 312 321(全排列!)

9.4 STL 函数对象——让函数也能当"参数"

4.1 什么是函数对象(仿函数)?

函数对象就是重载了 () 运算符的类,它的对象可以像函数一样被调用。

#include <iostream>
using namespace std;

// 定义一个函数对象类
class Multiplier {
    int factor;
public:
    Multiplier(int f) : factor(f) {}
    
    // 重载 () 运算符
    int operator()(int x) const {
        return x * factor;
    }
};

int main() {
    Multiplier times2(2);   // 创建一个"乘以2"的函数对象
    Multiplier times3(3);   // 创建一个"乘以3"的函数对象

    cout << times2(5) << endl;  // 10(像函数一样调用!)
    cout << times3(5) << endl;  // 15

    // 可以传给 STL 算法
    vector<int> v = {1, 2, 3, 4, 5};
    transform(v.begin(), v.end(), v.begin(), times2);
    for (int x : v) cout << x << " ";  // 2 4 6 8 10
    cout << endl;

    return 0;
}

💡 函数对象比普通函数强大的地方在于:它可以携带状态(成员变量)。

4.2 STL 内置的函数对象

STL 在 <functional> 头文件中提供了一堆现成的函数对象:

#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    // 算术类
    plus<int> add;
    cout << add(3, 4) << endl;        // 7

    minus<int> sub;
    cout << sub(10, 3) << endl;       // 7

    multiplies<int> mul;
    cout << mul(3, 4) << endl;        // 12

    divides<int> div;
    cout << div(10, 3) << endl;       // 3

    modulus<int> mod;
    cout << mod(10, 3) << endl;       // 1

    negate<int> neg;
    cout << neg(5) << endl;           // -5

    // 关系类
    greater<int> gt;
    cout << gt(5, 3) << endl;         // 1(true)

    less<int> lt;
    cout << lt(5, 3) << endl;         // 0(false)

    // 用在排序中
    vector<int> v = {5, 2, 8, 1, 9};
    sort(v.begin(), v.end(), greater<int>());  // 降序排序
    for (int x : v) cout << x << " ";  // 9 8 5 2 1
    cout << endl;

    return 0;
}

4.3 Lambda 表达式:匿名函数对象(C++11)

Lambda 表达式就是一种没有名字的、写在一行里的函数对象。它是函数对象的"语法糖"。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // Lambda 表达式语法:
    // [捕获列表](参数列表) -> 返回类型 { 函数体 }

    // 示例1:打印偶数
    for_each(v.begin(), v.end(), [](int x) {
        if (x % 2 == 0) cout << x << " ";
    });
    cout << endl;  // 2 4 6 8 10

    // 示例2:自定义排序(按个位数排序)
    vector<int> v2 = {23, 15, 47, 8, 32};
    sort(v2.begin(), v2.end(), [](int a, int b) {
        return (a % 10) < (b % 10);
    });
    for (int x : v2) cout << x << " ";  // 32 23 15 47 8
    cout << endl;

    // 示例3:捕获外部变量
    int threshold = 5;
    auto count = count_if(v.begin(), v.end(), [threshold](int x) {
        return x > threshold;  // 捕获了外部的 threshold
    });
    cout << "大于 " << threshold << " 的有 " << count << " 个" << endl;  // 5 个

    // 示例4:Lambda 的各种捕获方式
    int a = 10, b = 20;

    auto f1 = [a]()   { cout << a << endl; };     // 值捕获(只读)
    auto f2 = [&a]()  { a = 100; };               // 引用捕获(可修改)
    auto f3 = [=]()   { cout << a << b << endl; };// 值捕获所有外部变量
    auto f4 = [&]()   { a = 1; b = 2; };          // 引用捕获所有外部变量

    f2();   // a 被修改为 100
    cout << "a = " << a << endl;  // 100

    return 0;
}

🎯 Lambda 表达式速记

  • [] 不捕获任何变量
  • [x] 值捕获 x(只读)
  • [&x] 引用捕获 x(可修改)
  • [=] 值捕获所有外部变量
  • [&] 引用捕获所有外部变量

4.4 函数对象 vs 普通函数 vs Lambda

// 方式一:普通函数
bool compareDesc(int a, int b) { return a > b; }

// 方式二:函数对象
struct DescCompare {
    bool operator()(int a, int b) const { return a > b; }
};

// 方式三:Lambda(最简洁!)

int main() {
    vector<int> v = {5, 2, 8, 1, 9};

    sort(v.begin(), v.end(), compareDesc);    // 普通函数
    sort(v.begin(), v.end(), DescCompare());  // 函数对象
    sort(v.begin(), v.end(), [](int a, int b) { return a > b; });  // Lambda

    // 三种方式效果完全相同!Lambda 最简洁。
}

实战综合案例:学生成绩管理系统

把前面学的所有 STL 知识串起来,写一个完整的例子:

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <numeric>
#include <string>
using namespace std;

struct Student {
    string name;
    int age;
    vector<int> scores;  // 多门课的成绩

    double avgScore() const {
        if (scores.empty()) return 0;
        return accumulate(scores.begin(), scores.end(), 0.0) / scores.size();
    }
};

int main() {
    // ===== 1. 用 vector 存储学生信息 =====
    vector<Student> students = {
        {"张三", 20, {90, 85, 78}},
        {"李四", 21, {75, 88, 91}},
        {"王五", 19, {95, 92, 88}},
        {"赵六", 20, {60, 65, 70}},
        {"钱七", 22, {88, 90, 85}}
    };

    // ===== 2. 用 sort + Lambda 按平均分降序排序 =====
    sort(students.begin(), students.end(), [](const Student& a, const Student& b) {
        return a.avgScore() > b.avgScore();
    });

    cout << "=== 成绩排名 ===" << endl;
    for (size_t i = 0; i < students.size(); i++) {
        cout << "第" << i + 1 << "名: " << students[i].name
             << " 平均分: " << students[i].avgScore() << endl;
    }

    // ===== 3. 用 map 统计各年龄段人数 =====
    map<int, int> ageCount;
    for (auto& s : students) {
        ageCount[s.age]++;
    }

    cout << "\n=== 年龄分布 ===" << endl;
    for (auto& p : ageCount) {
        cout << p.first << " 岁: " << p.second << " 人" << endl;
    }

    // ===== 4. 用 find_if 查找最高分 =====
    auto best = max_element(students.begin(), students.end(),
        [](const Student& a, const Student& b) {
            return a.avgScore() < b.avgScore();
        });
    cout << "\n最高分: " << best->name << " (" << best->avgScore() << ")" << endl;

    // ===== 5. 用 count_if 统计及格人数(平均分 >= 60)=====
    int passCount = count_if(students.begin(), students.end(),
        [](const Student& s) { return s.avgScore() >= 60; });
    cout << "及格人数: " << passCount << "/" << students.size() << endl;

    // ===== 6. 用 transform 提取所有人的名字 =====
    vector<string> names;
    transform(students.begin(), students.end(), back_inserter(names),
        [](const Student& s) { return s.name; });

    cout << "\n=== 所有学生 ===" << endl;
    for (auto& name : names) cout << name << " ";
    cout << endl;

    return 0;
}

输出:

=== 成绩排名 ===
第1名: 王五 平均分: 91.6667
第2名: 钱七 平均分: 87.6667
第3名: 李四 平均分: 84.6667
第4名: 张三 平均分: 84.3333
第5名: 赵六 平均分: 65

=== 年龄分布 ===
19 岁: 1 人
20 岁: 2 人
21 岁: 1 人
22 岁: 1 人

最高分: 王五 (91.6667)
及格人数: 5/5

=== 所有学生 ===
王五 钱七 李四 张三 赵六

总结:STL 知识全景图

STL 编程
│
├── 📦 容器(数据的"房子")
│   ├── 顺序容器:vector / list / deque
│   │   → 按插入顺序存储,选择取决于增删模式
│   └── 关联容器:set / multiset / map / multimap
│       → 按键自动排序,查找效率 O(log n)
│
├── ⚙️ 算法(数据的"处理器")
│   ├── 遍历:for_each
│   ├── 排序:sort
│   ├── 查找:find / binary_search / count / find_if
│   ├── 去重:unique
│   ├── 变换:transform
│   └── 其他:accumulate / reverse / swap / next_permutation
│
├── 🔗 迭代器(容器和算法的"桥梁")
│   → begin() / end() / rbegin() / rend()
│   → 支持 ++ / -- / * / - 等操作
│
└── 🎭 函数对象(算法的"定制化参数")
    ├── 仿函数:重载 () 的类
    ├── STL 内置:greater<> / less<> / plus<> 等
    └── Lambda:匿名函数对象,最简洁的写法

🎯 一句话总结:STL 的设计哲学是——容器负责存,算法负责处理,迭代器负责连接,函数对象负责定制。四者配合,就能用最少的代码解决最多的问题。


如果觉得有帮助,欢迎点赞收藏 👍 有问题可以在评论区讨论!

更多推荐