C++学习笔记-Lambda表达式

Lambda表达式是C++11引入的匿名函数功能,允许在需要函数对象的地方定义内联函数。Lambda特别适用于短小的、只在特定地方使用的函数,可以让代码更简洁和易读。

Lambda的基本语法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <vector>
#include <functional>

void ForEach(const std::vector<int>& values, const std::function<void(int)>& func)
{
    for (int value : values)
        func(value);
}

int main()
{
    std::vector<int> values = {1, 2, 3, 4, 5};
    
    // 基本的Lambda表达式
    // [捕获列表](参数列表) { 函数体 }
    ForEach(values, [](int value) {
        std::cout << "Value: " << value << std::endl;
    });
    
    // Lambda的完整语法
    // [捕获列表](参数列表) -> 返回类型 { 函数体 }
    auto lambda = [](int a, int b) -> int {
        return a + b;
    };
    
    int result = lambda(10, 20);
    std::cout << "Lambda result: " << result << std::endl;
    
    // 无参数的Lambda
    auto greet = []() {
        std::cout << "Hello from Lambda!" << std::endl;
    };
    greet();
    
    // 省略参数列表(当无参数时)
    auto greet2 = [] {
        std::cout << "Hello again!" << std::endl;
    };
    greet2();
    
    return 0;
}

Lambda的捕获方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>

int main()
{
    int x = 10;
    int y = 20;
    
    std::cout << "=== Lambda Capture Examples ===" << std::endl;
    
    // 1. 值捕获 [x] - 捕获x的副本
    auto lambda1 = [x]() {
        std::cout << "Value capture x: " << x << std::endl;
        // x = 30;  // 错误:值捕获的变量是const的,不能修改
    };
    lambda1();
    
    // 2. 引用捕获 [&x] - 捕获x的引用
    auto lambda2 = [&x]() {
        std::cout << "Reference capture x before: " << x << std::endl;
        x = 30;  // 可以修改原变量
        std::cout << "Reference capture x after: " << x << std::endl;
    };
    lambda2();
    std::cout << "x after lambda2: " << x << std::endl;
    
    // 3. 混合捕获 [x, &y] - x按值捕获,y按引用捕获
    auto lambda3 = [x, &y]() {
        std::cout << "Mixed capture - x: " << x << ", y: " << y << std::endl;
        y = 40;  // 可以修改y
        // x = 50;  // 错误:不能修改值捕获的x
    };
    lambda3();
    std::cout << "y after lambda3: " << y << std::endl;
    
    // 4. 值捕获所有外部变量 [=]
    auto lambda4 = [=]() {
        std::cout << "Capture all by value - x: " << x << ", y: " << y << std::endl;
    };
    lambda4();
    
    // 5. 引用捕获所有外部变量 [&]
    auto lambda5 = [&]() {
        std::cout << "Capture all by reference - x: " << x << ", y: " << y << std::endl;
        x = 50;
        y = 60;
    };
    lambda5();
    std::cout << "After lambda5 - x: " << x << ", y: " << y << std::endl;
    
    // 6. 混合捕获 [=, &y] - 默认值捕获,y引用捕获
    int z = 100;
    auto lambda6 = [=, &y]() {
        std::cout << "Mixed default capture - x: " << x << ", y: " << y << ", z: " << z << std::endl;
        y = 70;  // 可以修改y
        // x = 80;  // 错误:不能修改值捕获的x
    };
    lambda6();
    
    // 7. mutable关键字 - 允许修改值捕获的变量
    auto lambda7 = [x]() mutable {
        std::cout << "Mutable lambda x before: " << x << std::endl;
        x = 90;  // 现在可以修改了,但只是修改副本
        std::cout << "Mutable lambda x after: " << x << std::endl;
    };
    lambda7();
    std::cout << "Original x after mutable lambda: " << x << std::endl;  // 原变量未改变
    
    return 0;
}

Lambda在STL算法中的应用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

int main()
{
    std::vector<int> numbers = {5, 2, 8, 1, 9, 3, 7, 4, 6};
    
    std::cout << "Original numbers: ";
    for (int num : numbers) std::cout << num << " ";
    std::cout << std::endl;
    
    // 1. std::for_each - 遍历每个元素
    std::cout << "Squared numbers: ";
    std::for_each(numbers.begin(), numbers.end(), [](int n) {
        std::cout << n * n << " ";
    });
    std::cout << std::endl;
    
    // 2. std::find_if - 查找满足条件的元素
    auto found = std::find_if(numbers.begin(), numbers.end(), [](int n) {
        return n > 5;
    });
    if (found != numbers.end()) {
        std::cout << "First number > 5: " << *found << std::endl;
    }
    
    // 3. std::count_if - 计算满足条件的元素数量
    int evenCount = std::count_if(numbers.begin(), numbers.end(), [](int n) {
        return n % 2 == 0;
    });
    std::cout << "Even numbers count: " << evenCount << std::endl;
    
    // 4. std::sort - 自定义排序
    std::vector<int> sortedNumbers = numbers;
    std::sort(sortedNumbers.begin(), sortedNumbers.end(), [](int a, int b) {
        return a > b;  // 降序排序
    });
    std::cout << "Descending order: ";
    for (int num : sortedNumbers) std::cout << num << " ";
    std::cout << std::endl;
    
    // 5. std::transform - 变换每个元素
    std::vector<int> doubled(numbers.size());
    std::transform(numbers.begin(), numbers.end(), doubled.begin(), [](int n) {
        return n * 2;
    });
    std::cout << "Doubled numbers: ";
    for (int num : doubled) std::cout << num << " ";
    std::cout << std::endl;
    
    // 6. std::remove_if - 移除满足条件的元素
    std::vector<int> filtered = numbers;
    auto newEnd = std::remove_if(filtered.begin(), filtered.end(), [](int n) {
        return n < 5;
    });
    filtered.erase(newEnd, filtered.end());
    std::cout << "Numbers >= 5: ";
    for (int num : filtered) std::cout << num << " ";
    std::cout << std::endl;
    
    // 7. std::accumulate - 自定义累加
    int product = std::accumulate(numbers.begin(), numbers.end(), 1, [](int acc, int n) {
        return acc * n;
    });
    std::cout << "Product of all numbers: " << product << std::endl;
    
    return 0;
}

Lambda的高级特性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <vector>
#include <functional>

int main()
{
    std::cout << "=== Advanced Lambda Features ===" << std::endl;
    
    // 1. 泛型Lambda (C++14)
    auto genericLambda = [](auto a, auto b) {
        return a + b;
    };
    
    std::cout << "Generic lambda with ints: " << genericLambda(10, 20) << std::endl;
    std::cout << "Generic lambda with doubles: " << genericLambda(3.14, 2.86) << std::endl;
    std::cout << "Generic lambda with strings: " << genericLambda(std::string("Hello"), std::string(" World")) << std::endl;
    
    // 2. 初始化捕获 (C++14)
    int x = 10;
    auto initCapture = [y = x * 2, z = std::string("captured")](int param) {
        std::cout << "Init capture - y: " << y << ", z: " << z << ", param: " << param << std::endl;
    };
    initCapture(100);
    
    // 3. 移动捕获
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto moveCapture = [v = std::move(vec)]() {
        std::cout << "Moved vector size: " << v.size() << std::endl;
        for (int num : v) std::cout << num << " ";
        std::cout << std::endl;
    };
    moveCapture();
    std::cout << "Original vector size after move: " << vec.size() << std::endl;
    
    // 4. 递归Lambda
    std::function<int(int)> factorial = [&factorial](int n) -> int {
        return n <= 1 ? 1 : n * factorial(n - 1);
    };
    std::cout << "Factorial of 5: " << factorial(5) << std::endl;
    
    // 5. 立即调用的Lambda表达式 (IIFE)
    int result = [](int a, int b) {
        return a * b + 10;
    }(5, 6);
    std::cout << "IIFE result: " << result << std::endl;
    
    // 6. 返回Lambda的函数
    auto createMultiplier = [](int factor) {
        return [factor](int value) {
            return value * factor;
        };
    };
    
    auto doubler = createMultiplier(2);
    auto tripler = createMultiplier(3);
    
    std::cout << "Doubler(10): " << doubler(10) << std::endl;
    std::cout << "Tripler(10): " << tripler(10) << std::endl;
    
    return 0;
}

Lambda与函数对象的比较

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>

// 传统函数对象
class Multiplier
{
private:
    int m_Factor;
    
public:
    Multiplier(int factor) : m_Factor(factor) {}
    
    int operator()(int value) const
    {
        return value * m_Factor;
    }
};

// 普通函数
bool IsEven(int n)
{
    return n % 2 == 0;
}

void ComparisonExample()
{
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    std::cout << "=== Lambda vs Function Object vs Function ===" << std::endl;
    
    // 1. 使用函数对象
    std::cout << "Using function object:" << std::endl;
    Multiplier doubler(2);
    std::vector<int> result1(numbers.size());
    std::transform(numbers.begin(), numbers.end(), result1.begin(), doubler);
    for (int num : result1) std::cout << num << " ";
    std::cout << std::endl;
    
    // 2. 使用Lambda
    std::cout << "Using lambda:" << std::endl;
    std::vector<int> result2(numbers.size());
    std::transform(numbers.begin(), numbers.end(), result2.begin(), [](int n) {
        return n * 2;
    });
    for (int num : result2) std::cout << num << " ";
    std::cout << std::endl;
    
    // 3. 使用普通函数
    std::cout << "Using function:" << std::endl;
    int evenCount = std::count_if(numbers.begin(), numbers.end(), IsEven);
    std::cout << "Even count with function: " << evenCount << std::endl;
    
    // 4. 使用Lambda(相同功能)
    int evenCountLambda = std::count_if(numbers.begin(), numbers.end(), [](int n) {
        return n % 2 == 0;
    });
    std::cout << "Even count with lambda: " << evenCountLambda << std::endl;
}

void PerformanceComparison()
{
    const int SIZE = 1000000;
    const int ITERATIONS = 100;
    std::vector<int> data(SIZE);
    std::iota(data.begin(), data.end(), 1);
    
    // Lambda性能测试
    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        volatile int count = std::count_if(data.begin(), data.end(), [](int n) {
            return n % 2 == 0;
        });
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto lambdaTime = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    // 函数对象性能测试
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        volatile int count = std::count_if(data.begin(), data.end(), [](int n) {
            return n % 2 == 0;
        });
    }
    end = std::chrono::high_resolution_clock::now();
    auto functorTime = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    // 普通函数性能测试
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        volatile int count = std::count_if(data.begin(), data.end(), IsEven);
    }
    end = std::chrono::high_resolution_clock::now();
    auto functionTime = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    std::cout << "\nPerformance comparison (" << ITERATIONS << " iterations):" << std::endl;
    std::cout << "Lambda: " << lambdaTime.count() << " ms" << std::endl;
    std::cout << "Function object: " << functorTime.count() << " ms" << std::endl;
    std::cout << "Function: " << functionTime.count() << " ms" << std::endl;
}

int main()
{
    ComparisonExample();
    PerformanceComparison();
    return 0;
}

Lambda的实际应用场景

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <functional>

// 事件处理系统
class Button
{
public:
    using ClickHandler = std::function<void()>;
    
private:
    std::string m_Name;
    ClickHandler m_OnClick;
    
public:
    Button(const std::string& name) : m_Name(name) {}
    
    void SetOnClick(const ClickHandler& handler)
    {
        m_OnClick = handler;
    }
    
    void Click()
    {
        std::cout << "Button '" << m_Name << "' clicked!" << std::endl;
        if (m_OnClick)
        {
            m_OnClick();
        }
    }
};

// 数据处理管道
class DataPipeline
{
public:
    using Processor = std::function<int(int)>;
    
private:
    std::vector<Processor> m_Processors;
    
public:
    void AddProcessor(const Processor& processor)
    {
        m_Processors.push_back(processor);
    }
    
    std::vector<int> Process(const std::vector<int>& input)
    {
        std::vector<int> result = input;
        
        for (const auto& processor : m_Processors)
        {
            std::transform(result.begin(), result.end(), result.begin(), processor);
        }
        
        return result;
    }
};

// 配置驱动的行为
class ConfigurableProcessor
{
public:
    using FilterPredicate = std::function<bool(int)>;
    using TransformFunction = std::function<int(int)>;
    
private:
    FilterPredicate m_Filter;
    TransformFunction m_Transform;
    
public:
    void SetFilter(const FilterPredicate& filter)
    {
        m_Filter = filter;
    }
    
    void SetTransform(const TransformFunction& transform)
    {
        m_Transform = transform;
    }
    
    std::vector<int> Process(const std::vector<int>& input)
    {
        std::vector<int> result;
        
        for (int value : input)
        {
            if (!m_Filter || m_Filter(value))
            {
                int transformed = m_Transform ? m_Transform(value) : value;
                result.push_back(transformed);
            }
        }
        
        return result;
    }
};

int main()
{
    std::cout << "=== Practical Lambda Applications ===" << std::endl;
    
    // 1. 事件处理
    std::cout << "1. Event Handling:" << std::endl;
    Button saveButton("Save");
    Button loadButton("Load");
    
    saveButton.SetOnClick([]() {
        std::cout << "  Saving file..." << std::endl;
    });
    
    loadButton.SetOnClick([]() {
        std::cout << "  Loading file..." << std::endl;
    });
    
    saveButton.Click();
    loadButton.Click();
    
    // 2. 数据处理管道
    std::cout << "\n2. Data Processing Pipeline:" << std::endl;
    DataPipeline pipeline;
    
    // 添加处理步骤
    pipeline.AddProcessor([](int x) { return x * 2; });      // 乘以2
    pipeline.AddProcessor([](int x) { return x + 10; });     // 加10
    pipeline.AddProcessor([](int x) { return x * x; });      // 平方
    
    std::vector<int> input = {1, 2, 3, 4, 5};
    auto output = pipeline.Process(input);
    
    std::cout << "Input: ";
    for (int val : input) std::cout << val << " ";
    std::cout << std::endl;
    
    std::cout << "Output: ";
    for (int val : output) std::cout << val << " ";
    std::cout << std::endl;
    
    // 3. 配置驱动的处理
    std::cout << "\n3. Configurable Processing:" << std::endl;
    ConfigurableProcessor processor;
    
    // 只处理偶数
    processor.SetFilter([](int x) { return x % 2 == 0; });
    // 转换为立方
    processor.SetTransform([](int x) { return x * x * x; });
    
    std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    auto filtered = processor.Process(data);
    
    std::cout << "Original: ";
    for (int val : data) std::cout << val << " ";
    std::cout << std::endl;
    
    std::cout << "Filtered and transformed: ";
    for (int val : filtered) std::cout << val << " ";
    std::cout << std::endl;
    
    // 4. 排序和搜索的自定义逻辑
    std::cout << "\n4. Custom Sorting and Searching:" << std::endl;
    
    struct Person
    {
        std::string name;
        int age;
        double salary;
    };
    
    std::vector<Person> people = {
        {"Alice", 30, 75000},
        {"Bob", 25, 60000},
        {"Charlie", 35, 80000},
        {"Diana", 28, 70000}
    };
    
    // 按薪水排序
    std::sort(people.begin(), people.end(), [](const Person& a, const Person& b) {
        return a.salary > b.salary;
    });
    
    std::cout << "Sorted by salary (descending):" << std::endl;
    for (const auto& person : people)
    {
        std::cout << "  " << person.name << ": $" << person.salary << std::endl;
    }
    
    // 查找年龄大于30的第一个人
    auto found = std::find_if(people.begin(), people.end(), [](const Person& p) {
        return p.age > 30;
    });
    
    if (found != people.end())
    {
        std::cout << "First person over 30: " << found->name << " (age " << found->age << ")" << std::endl;
    }
    
    return 0;
}

总结

  1. Lambda本质:匿名函数,可以在需要的地方定义内联函数
  2. 基本语法[捕获列表](参数列表) -> 返回类型 { 函数体 }
  3. 捕获方式
    • 值捕获:[x] - 捕获x的副本
    • 引用捕获:[&x] - 捕获x的引用
    • 混合捕获:[=, &y] - 默认值捕获,y引用捕获
  4. 使用场景
    • 当函数很短小,只在某个特定地方使用时
    • STL算法的自定义操作
    • 事件处理和回调函数
    • 函数式编程风格
  5. 优势
    • 代码更简洁
    • 就地定义,逻辑更清晰
    • 可以捕获局部变量
    • 编译器优化友好
  6. 注意事项
    • 注意捕获方式的选择
    • 避免悬空引用
    • 复杂逻辑建议使用普通函数
updatedupdated2025-09-202025-09-20