C++11新特性-lambda表达式

C++11引入了Lambda表达式,它是一种在函数内部定义匿名函数的方式。Lambda表达式使得代码更加简洁和灵活,特别是在需要短小的函数对象时。

基本语法

Lambda表达式的基本语法如下:

[capture](parameters) -> return_type {
    // function body
}
  • capture:捕获列表,指定 Lambda 表达式可以访问外部变量的方式。
  • parameters:函数参数列表,类似于普通函数的参数。
  • return_type:返回类型,通常可以省略,编译器会自动推导。
  • function body:Lambda 表达式的主体,包含实际的代码。

示例

  1. 简单的 Lambda 表达式:

    auto add = [](int a, int b) {
        return a + b;
    };
    std::cout << add(3, 4); // 输出 7
    
  2. 带捕获列表的 Lambda 表达式:

    int x = 10;
    auto printX = [x]() {
        std::cout << x << std::endl;
    };
    printX(); // 输出 10
    

    在这个例子中,[x] 表示捕获外部变量 x 的值。x 是按值捕获的。

  3. 捕获外部变量的引用:

    int x = 10;
    auto incrementX = [&x]() {
        x++;
    };
    incrementX();
    std::cout << x; // 输出 11
    

    这里 &x 表示捕获外部变量 x 的引用,因此在 Lambda 表达式内对 x 的修改会影响到外部的 x

  4. 捕获所有变量(值捕获和引用捕获):

    int x = 10, y = 20;
    auto printXY = [=]() { // 捕获所有外部变量的值
        std::cout << x << " " << y << std::endl;
    };
    printXY(); // 输出 10 20
    
    auto modifyXY = [&]() { // 捕获所有外部变量的引用
        x = 30;
        y = 40;
    };
    modifyXY();
    std::cout << x << " " << y << std::endl; // 输出 30 40
    

    [=] 表示按值捕获所有外部变量,[&] 表示按引用捕获所有外部变量。

  5. 指定返回类型:

    auto divide = [](double a, double b) -> double {
        if (b == 0) throw std::runtime_error("Division by zero");
        return a / b;
    };
    std::cout << divide(10, 2); // 输出 5
    

    在这个例子中,-> double 明确指定了返回类型为 double

  6. 在 STL 算法中使用 Lambda 表达式:

    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::for_each(numbers.begin(), numbers.end(), [](int n) {
        std::cout << n << " ";
    });
    // 输出 1 2 3 4 5
    

    在 STL 算法中,Lambda 表达式通常用于简化回调函数的定义。

注意事项

  • 捕获列表的多样性: 捕获列表可以为空([]),或者只包含特定变量([x]),或者所有变量的值([=]),或者所有变量的引用([&]),也可以混合使用([=, &x])。
  • Lambda 表达式的类型: Lambda 表达式的类型是由编译器生成的一个特殊的函数对象类型,通常是匿名的。

Lambda 表达式提供了一种在函数内部定义并使用局部函数的方式,使代码更加灵活和易于阅读。

使用场景

Lambda 表达式在 C++ 中提供了一种简洁且强大的方法来创建匿名函数对象。它们适用于各种场景,包括回调函数、算法操作、事件处理等。下面是一些常见的使用场景和具体用法示例:

1. STL 算法中的回调

Lambda 表达式经常用于 STL 算法中的回调函数,例如 std::sortstd::for_eachstd::find_if 等。

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

int main() {
    std::vector<int> numbers = {5, 2, 9, 1, 5, 6};

    // 使用 Lambda 表达式对向量进行排序
    std::sort(numbers.begin(), numbers.end(), [](int a, int b) {
        return a < b;
    });

    // 打印排序后的向量
    std::for_each(numbers.begin(), numbers.end(), [](int n) {
        std::cout << n << " ";
    });

    return 0;
}

2. 事件处理

Lambda 表达式可以用于事件处理,特别是在 GUI 编程中,例如使用 Qt 或其他事件驱动框架。

#include <QPushButton>
#include <QApplication>
#include <QMessageBox>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QPushButton button("Click me");
    QObject::connect(&button, &QPushButton::clicked, [&]() {
        QMessageBox::information(nullptr, "Message", "Button clicked!");
    });

    button.show();
    return app.exec();
}

3. 自定义比较函数

在需要自定义比较逻辑的地方,Lambda 表达式可以简化代码。

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

int main() {
    std::vector<int> numbers = {10, 20, 30, 40, 50};

    // 使用 Lambda 表达式找到第一个大于 25 的元素
    auto it = std::find_if(numbers.begin(), numbers.end(), [](int n) {
        return n > 25;
    });

    if (it != numbers.end()) {
        std::cout << "First number greater than 25 is: " << *it << std::endl;
    }

    return 0;
}

4. 简化回调函数

Lambda 表达式可以替代传统的函数对象或函数指针,简化回调函数的定义。

#include <iostream>
#include <functional>

void process(std::function<void()> callback) {
    // 执行回调
    callback();
}

int main() {
    // 使用 Lambda 表达式作为回调函数
    process([]() {
        std::cout << "Callback executed!" << std::endl;
    });

    return 0;
}

5. 生成函数对象

在需要生成函数对象时,Lambda 表达式可以使代码更简洁。

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

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

    // 使用 Lambda 表达式生成平方函数对象
    std::transform(numbers.begin(), numbers.end(), numbers.begin(), [](int n) {
        return n * n;
    });

    // 打印结果
    for (int n : numbers) {
        std::cout << n << " ";
    }

    return 0;
}

6. 捕获外部变量

Lambda 表达式能够捕获外部变量,使得在闭包中可以访问这些变量。

#include <iostream>

int main() {
    int x = 10;
    auto lambda = [x]() mutable { // `mutable` 允许修改捕获的 `x`
        std::cout << "Captured x: " << x << std::endl;
        x += 5;
        std::cout << "Modified x: " << x << std::endl;
    };

    lambda();
    std::cout << "Outside x: " << x << std::endl; // 输出 10

    return 0;
}

7. 延迟执行

Lambda 表达式可以延迟执行,适用于生成惰性计算的代码。

#include <iostream>
#include <functional>

int main() {
    int a = 5, b = 10;

    // 延迟计算
    auto delayedSum = [a, b]() {
        return a + b;
    };

    std::cout << "Delayed sum: " << delayedSum() << std::endl;

    return 0;
}

总结

Lambda 表达式在 C++ 中提供了一种方便的方式来定义临时的匿名函数对象。它们在需要简洁、局部的函数逻辑时非常有用,尤其是在 STL 算法、事件处理、回调函数、自定义比较、生成函数对象等场景中。使用 Lambda 表达式可以使代码更加清晰、可维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值