欢迎光临
我们一直在努力

C++ Lambda表达式:从入门到精通

一、Lambda 表达式简介

Lambda 表达式是 C++11 标准引入的特性,用于创建匿名函数对象(闭包)。它允许你在代码中直接定义一个函数,而无需显式命名。基本语法结构如下:

[capture](parameters) mutable -> return_type {
// 函数体
}

各部分含义:

  • [capture] (捕获列表):定义 Lambda 表达式如何访问外部变量
  • (parameters) (参数列表):与普通函数参数列表类似
  • mutable (可选项):允许修改捕获的值变量(不影响外部变量)
  • -> return_type (可选项):显式指定返回类型
  • { } (函数体):包含要执行的代码
  • 二、捕获列表详解

    捕获方式决定了 Lambda 如何访问外部作用域的变量:

  • 值捕获:创建变量副本

    int a = 10;
    auto lambda = [a] { return a * 2; }; // 捕获a的值

  • 引用捕获:直接操作原变量

    int b = 20;
    auto lambda = [&b] { b += 5; }; // 通过引用修改b

  • 隐式捕获:
    • [=]:捕获所有外部变量(值方式)
    • [&]:捕获所有外部变量(引用方式)
    • [=, &x]:值捕获所有变量,但x用引用捕获
  • 三、典型应用场景

  • STL 算法:

    std::vector<int> nums{3,1,4,2};
    std::sort(nums.begin(), nums.end(),
    [](int a, int b) { return a > b; }); // 降序排序

  • 异步编程:

    std::thread t([=] {
    std::cout << "Value captured: " << a << std::endl;
    });
    t.join();

  • 延迟执行:

    auto defer = [](auto func) {
    return std::make_shared<std::function<void()>>(func);
    };

  • 四、C++14/17 增强特性

  • 泛型 Lambda(C++14):

    auto generic = [](auto x, auto y) { return x + y; };

  • constexpr Lambda(C++17):

    constexpr auto square = [](int n) { return n * n; };
    static_assert(square(5) == 25);

  • 五、注意事项

  • 生命周期管理:引用捕获需确保被引对象生命周期长于 Lambda
  • 返回值推导:当函数体含多条语句时建议显式声明返回类型
  • mutable 修饰:若需修改值捕获的副本必须使用 mutable

    int counter = 0;
    auto inc = [counter]() mutable { return ++counter; }; // 修改副本

  • 六、示例:自定义比较器

    #include <iostream>
    #include <vector>
    #include <algorithm>

    int main() {
    std::vector<std::string> words{"apple", "banana", "cherry"};

    // 按长度排序
    std::sort(words.begin(), words.end(),
    [](const std::string& a, const std::string& b) {
    return a.length() < b.length();
    });

    for (const auto& w : words) {
    std::cout << w << " ";
    }
    // 输出:apple cherry banana
    }

    Lambda 表达式极大提升了代码的灵活性和简洁性,是现代 C++ 开发的核心工具之一。

    好的,我们来详细讲解 C++ 中的 Lambda 表达式。

    一、Lambda 表达式简介

    Lambda 表达式是 C++11 标准引入的特性,用于创建匿名函数对象(闭包)。它允许你在代码中直接定义一个函数,而无需显式命名。基本语法结构如下:

    [capture](parameters) mutable -> return_type {
    // 函数体
    }

    各部分含义:

  • [capture] (捕获列表):定义 Lambda 表达式如何访问外部变量
  • (parameters) (参数列表):与普通函数参数列表类似
  • mutable (可选项):允许修改捕获的值变量(不影响外部变量)
  • -> return_type (可选项):显式指定返回类型
  • { } (函数体):包含要执行的代码
  • 二、捕获列表详解

    捕获方式决定了 Lambda 如何访问外部作用域的变量:

  • 值捕获:创建变量副本

    int a = 10;
    auto lambda = [a] { return a * 2; }; // 捕获a的值

  • 引用捕获:直接操作原变量

    int b = 20;
    auto lambda = [&b] { b += 5; }; // 通过引用修改b

  • 隐式捕获:
    • [=]:捕获所有外部变量(值方式)
    • [&]:捕获所有外部变量(引用方式)
    • [=, &x]:值捕获所有变量,但x用引用捕获
  • 三、典型应用场景

  • STL 算法:

    std::vector<int> nums{3,1,4,2};
    std::sort(nums.begin(), nums.end(),
    [](int a, int b) { return a > b; }); // 降序排序

  • 异步编程:

    std::thread t([=] {
    std::cout << "Value captured: " << a << std::endl;
    });
    t.join();

  • 延迟执行:

    auto defer = [](auto func) {
    return std::make_shared<std::function<void()>>(func);
    };

  • 四、C++14/17 增强特性

  • 泛型 Lambda(C++14):

    auto generic = [](auto x, auto y) { return x + y; };

  • constexpr Lambda(C++17):

    constexpr auto square = [](int n) { return n * n; };
    static_assert(square(5) == 25);

  • 五、注意事项

  • 生命周期管理:引用捕获需确保被引对象生命周期长于 Lambda
  • 返回值推导:当函数体含多条语句时建议显式声明返回类型
  • mutable 修饰:若需修改值捕获的副本必须使用 mutable

    int counter = 0;
    auto inc = [counter]() mutable { return ++counter; }; // 修改副本

  • 六、示例:自定义比较器

    #include <iostream>
    #include <vector>
    #include <algorithm>

    int main() {
    std::vector<std::string> words{"apple", "banana", "cherry"};

    // 按长度排序
    std::sort(words.begin(), words.end(),
    [](const std::string& a, const std::string& b) {
    return a.length() < b.length();
    });

    for (const auto& w : words) {
    std::cout << w << " ";
    }
    // 输出:apple cherry banana
    }

    Lambda 表达式极大提升了代码的灵活性和简洁性,是现代 C++ 开发的核心工具之一。

    赞(0)
    未经允许不得转载:171主机测评 » C++ Lambda表达式:从入门到精通
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址