C++高级特性详解
🔷 一、mutable:让值捕获可修改
值捕获默认是 const,加 mutable 后可以修改副本(不影响外部):
cpp
int count = 0;
auto counter = [count]() mutable {
count++; // ✅ 修改的是副本
return count;
};
counter(); // → 1
counter(); // → 2
count; // → 0,外部完全不受影响!
对比引用捕获:
cpp
auto counter2 = [&count]() {
count++;
};
counter2(); // count → 1
counter2(); // count → 2
count; // → 2,外部被修改了
选择原则:想要”内部计数”但不污染外部 →
mutable值捕获;想同步外部状态 → 引用捕获。
🔷 二、STL 算法中的 Lambda 实战
sort — 自定义排序
cpp
std::vector<std::string> words = {"banana", "apple", "cherry", "fig"};
// 按字符串长度排序
std::sort(words.begin(), words.end(),
[](const std::string& a, const std::string& b) {
return a.size() < b.size();
});
// → fig, apple, banana, cherry
find_if — 条件查找
cpp
std::vector<int> v = {3, 7, 2, 9, 4};
int threshold = 6;
auto it = std::find_if(v.begin(), v.end(),
[threshold](int x) { return x > threshold; } // 捕获阈值
);
if (it != v.end())
std::cout << *it; // → 7(第一个大于6的元素)
transform — 批量变换
cpp
std::vector<int> v = {1, 2, 3, 4, 5};
std::vector<int> result(v.size());
std::transform(v.begin(), v.end(), result.begin(),
[](int x) { return x * x; }
);
// result → {1, 4, 9, 16, 25}
for_each + remove_if — 过滤
cpp
std::vector<int> v = {1, 2, 3, 4, 5, 6};
// 删除所有偶数
v.erase(
std::remove_if(v.begin(), v.end(),
[](int x) { return x % 2 == 0; }),
v.end()
);
// v → {1, 3, 5}
🔷 三、并发中的 Lambda 配合 std::thread
基本用法
cpp
#include <thread>
std::thread t([]() {
std::cout << "子线程运行中" << std::endl;
});
t.join(); // 主线程等待子线程结束
传参给线程
cpp
auto task = [](int id, std::string msg) {
std::cout << "线程" << id << ": " << msg << std::endl;
};
std::thread t1(task, 1, "hello");
std::thread t2(task, 2, "world");
t1.join();
t2.join();
⚠️ 并发中的引用捕获陷阱
cpp
// ❌ 危险:主线程结束后 data 已销毁
std::vector<int> data = {1, 2, 3};
std::thread t([&data]() {
// 如果主线程先结束,data 悬空!
for (auto x : data) std::cout << x;
});
t.detach(); // detach 后主线程不等子线程,极度危险
// ✅ 安全:值捕获,拷贝一份给线程
std::thread t([data]() { // 拷贝 data
for (auto x : data) std::cout << x;
});
t.join(); // 或确保 join 在 data 销毁前
共享数据用 mutex 保护
cpp
#include <mutex>
int total = 0;
std::mutex mtx;
auto addTask = [&total, &mtx](int val) {
std::lock_guard<std::mutex> lock(mtx); // 自动加锁/解锁
total += val;
};
std::thread t1(addTask, 10);
std::thread t2(addTask, 20);
t1.join();
t2.join();
std::cout << total; // → 30,安全!
🔷 综合对比总结
Lambda 能力图:
定义时绑定环境 调用时接收数据
[捕获] + (传参) = 完整的"小函数"
↓ ↓
值捕获(快照) 普通参数
引用捕获(共享)
mutable(可改副本)
↓
用于 STL 算法 / 线程 / 回调 / 异步任务
下一步可以继续学:
std::async/std::future:更高级的异步任务- 模板 + Lambda:泛型回调
- C++20 的 Lambda 新特性(模板Lambda、
[=, this]等)
想继续哪个?
