intmain(){ // 模板 Lambda (C++20) auto make_pair = []<typename T, typename U>(T a, U b) { return std::pair{a, b}; }; auto p = make_pair(1, 3.14); std::cout << p.first << ", " << p.second << "\n"; // initializer_list lambda auto vec = []<typename T>(std::initializer_list<T> init) { return std::vector<T>(init); }; auto v = vec({1, 2, 3, 4, 5}); // [=, *this] 捕获 classWidget { public: int data = 42; voidprocess(){ auto f = [=, *this]() { std::cout << data << "\n"; // copy of *this }; f(); } }; Widget w; w.process(); // constexpr lambda constexprauto add = [](auto a, auto b) { return a + b; }; static_assert(add(1, 2) == 3); // 泛型lambda with concept auto print_integral = []<std::integral T>(T n) { std::cout << n << " (integral)\n"; }; print_integral(42); }
运行结果:
1 2 3
1, 3.14 42 42 (integral)
七、Lambda 演进时间线
graph LR
A["C++11<br/>🟢 引入 Lambda<br/>基本功能"] --> B["C++14<br/>🟢 泛型 Lambda<br/>auto 参数"]
B --> C["C++17<br/>🟢 constexpr Lambda<br/>if constexpr"]
C --> D["C++20<br/>🟣 模板 Lambda<br/>*this 捕获<br/>Concepts 约束"]
style A fill:#B5EAD7,stroke:#80CBC4,color:#333
style B fill:#B5EAD7,stroke:#80CBC4,color:#333
style C fill:#B5EAD7,stroke:#80CBC4,color:#333
style D fill:#E8D5F5,stroke:#CE93D8,color:#333
八、常见错误与避坑
8.1 模板 Lambda 不能有默认参数
1 2 3 4 5
// ❌ 错误 auto f = []<typename T = int>(T x = 0) { }; // C++20 不支持!
// ✅ 正确:默认值在调用时指定 auto f = []<typename T>(T x = T{}) { };
8.2 [*this] vs [=] 的生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classConnection { std::string name = "conn"; public: voidonDisconnect(){ // ❌ 危险:[this] 捕获了指针 auto callback = [this]() { // 如果 this 已经被析构,这里是未定义行为! // std::cout << name << "\n"; }; } voidsafeOnDisconnect(){ // ✅ 安全:[*this] 捕获了对象的副本 auto callback = [=, *this]() { // name 是副本,永远有效 std::cout << name << "\n"; }; } };
8.3 mutable Lambda 与模板
1 2 3 4 5 6 7 8 9 10 11
intmain(){ int x = 0; // mutable 不影响模板参数推断 auto increment = [x]<typename T>(T y) mutable { x = 10; // 修改捕获的副本 return x + y; }; std::cout << increment(5) << "\n"; // 15 }
九、性能 considerations
Lambda 的性能零成本抽象——在编译期会被内联,没有额外运行时开销。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include<iostream> #include<chrono>
intmain(){ auto start = std::chrono::high_resolution_clock::now(); // 多次调用 Lambda auto add = [](int a, int b) { return a + b; }; for (int i = 0; i < 1'000'000; ++i) { volatileauto result = add(i, i + 1); } auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); std::cout << "Time: " << duration.count() << " us\n"; }