AndreaDO

导航

C++ lambda表达式

C++ lambda表达式,又称为闭包,匿名函数

入门语法

举个例子

 auto f = [](int a,int b){
        return a <b;
    };
    std::vector<int> vec = {0,11,2,23,4};
    std::sort(vec.begin(),vec.end(),f);

上面的就是通过一个简单的匿名函数来简化了排序,lambda表达式具体语法如下:

[OuterVar](int x,int y)->int {
  return OuterVar + x+y;
}

其中[]中OuterVar被称为捕获变量,可以有值或者为空,然后括号中包起来的是参数列表,箭头跟着返回类型,最后是函数体。其他lambda表达式的返回类型,编译器会自行推导,所以上面的代码中的->可以省略。下面和上面是等价的。

[OuterVar](int x,int y){
  return OuterVar + x+y;
}

变量的捕获(capture clause)

介绍捕获

让我们的匿名函数可以访问外部变量,甚至修改外部变量
举例

int N=100,M=10;
    auto g = [N,&M](int i)
    {
        M=20;
        return N*i;
    };
    std::cout<<g(10) <<"  "<<M<<std::endl;
//输出 1000  20

这里的N和M都被匿名函数访问了,M前有引用符号,表示按照引用来捕获。

[&]和[=] 捕获

[&]和[=]是两种常见的捕获模式,它们分别代表按引用捕获和按值捕获。

[&]:按引用捕获

使用&符号表示lambda表达式应该按引用捕获其封闭作用域中的所有变量。这意味着在lambda函数体内对捕获的变量的任何修改都会影响到原始变量。

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

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

    // 使用lambda表达式按引用捕获变量sum,并在lambda中修改它  
    int sum = 0;  
    std::for_each(numbers.begin(), numbers.end(), [&sum](int n) {  
        sum += n;  
    });  

    std::cout << "Sum: " << sum << std::endl;  // 输出:Sum: 15  
    return 0;  
}
//输出 Sum: 15

[=]:按值捕获

使用=符号表示lambda表达式应该按值捕获其封闭作用域中的所有变量。这意味着在lambda函数体内捕获的变量是原始变量的副本,对副本的任何修改都不会影响到原始变量。

注意不能对其中变量进行修改。

#include <iostream>  
  
int main() {  
    int x = 10;  
    int y = 20;  
  
    // 使用[=]按值捕获x和y  
    auto lambda = [=]() {  
        std::cout << "x = " << x << ", y = " << y << std::endl;  
        // 注意:不能修改x和y,因为它们是按值捕获的副本  
        // x=20; 这个代码编译器会报错
    };  
  
    // 调用lambda表达式  
    lambda();  
  
    return 0;  
}

其他捕获的知识

[this]  表示捕获当前实例的指针
[*this] 表示按值捕获该实例

在C++14后,你还可以在捕获语句中定义新变量

#include <iostream>  
int main() {  
    int x = 10;  
    int y = 20;  
    // 增加新变量k
    auto lambda = [x,y,k=5]() {  
        std::cout << "x = " << x << ", y = " << y <<   ", k = " << k << std::endl;  
        //  x = 10, y = 20, k = 5
    };  
    lambda();  
    return 0;  
}

在C++14后,lambda的参数列表支持auto类型,更加通用和泛化


    int x = 10;  
    int y = 20;  
  
    // 参数列表修改成auto类型
    auto lambda = [](auto x,auto y) {  
        std::cout << "x = " << x << ", y = " << y   << std::endl;  
        //  x = 10, y = 20, k = 5
    };  
  
    lambda(x,y);  
//输出 x = 10, y = 20

posted on 2024-02-20 12:10  AndreaDO  阅读(47)  评论(0)    收藏  举报