C++中的lambda表达式用法及示例

发布时间:2024-02-19 09:30

Lambda表达式(也叫lambda函数,或简称lambda),是从C++ 11开始引入并不断完善的,是能够捕获作用域中变量的匿名函数对象。因为C++是不能嵌套定义函数的,所以lambda就成了我们构造闭包的主要手段(和临时短函数)。本文主要展示lambda的基本使用。

lambda的基本语法如下:

 [capture](parameters)->return-type{body}

1. 如果没有参数,空的圆括号()可以省略。

2. 返回值也可以省略(无论返回类型是否为void),但是原则上,只有当函数体只由一条return语句组成或返回类型为void的话才这么做。形如: [capture](parameters){body}

关于capture里面的值如何获取:

[] //未定义变量.试图在Lambda内使用任何外部变量都是错误的.
[x, &y] //x 按值捕获, y 按引用捕获.
[&] //用到的任何外部变量都隐式按引用捕获
[=] //用到的任何外部变量都隐式按值捕获
[&, x] //x显式地按值捕获. 其它变量按引用捕获
[=, &z] //z按引用捕获. 其它变量按值捕获

对于lambda表达式,编译时会生成一个与lambda对应的新的(未命名的)类类型。

捕获列表 [ ]

捕获列表是空或多个捕获符的逗号分隔符列表。lambda的数据成员也在lambda对象创建时被初始化。

值捕获:

void func()
{
    int i = 100;//局部变量
    //将i拷贝到lambda表达式f的可调用对象,也就是把i是100这个值传到了f中,f中用的i一直就是100,不会改变。
    auto f = [i] { return i; };
    i = 0;
    int j = f(); //j=100,因为i是f创建时拷贝的,而不是运行时,所以即使后面i=0也不起作用。
    printf(\"j = %d\\n\",j);
}

\"C++中的lambda表达式用法及示例_第1张图片\"

引用捕获:

void func()
{
    int i = 100;//局部变量
    //对象f包含i的引用
    auto f = [&i] { return i; };//lambda表达式f的参数为i的地址。
    i = 0;
    int j = f(); //j=0,传递的是引用
    printf(\"j = %d\\n\",j);
}

 

\"C++中的lambda表达式用法及示例_第2张图片\"

 

形参列表 ( ) 

lambda形参列表和一般的函数形参列表类似,但不允许默认实参(C++14 前)。当以 auto 为形参类型时,该 lambda 为泛型 lambda(C++14 起)。与一个普通函数调用类似,调用一个lambda时给定的实参被用来初始化lambda的形参。

#include 

int main()
{
    int i = 1, j = 2;
    auto f = [](int a, int &b) {
        a = 10;
        b = 20;
        //输出:10  20
        std::cout << a << \" \" << b << std::endl;
    };
    f(i, j);
    //输出:1 20
    std::cout << i << \" \" << j << std::endl;
}

\"C++中的lambda表达式用法及示例_第3张图片\"


1.3.说明符 
允许以下说明符:

mutable:允许 函数体 修改各个复制捕获的对象,以及调用其非 const 成员函数;
constexpr:显式指定函数调用运算符为 constexpr 函数。此说明符不存在时,若函数调用运算符恰好满足针对 constexpr 函数的所有要求,则它也会是 constexpr;  (C++17 起)
consteval:指定函数调用运算符为立即函数。不能同时使用 consteval 和 constexpr。(C++20 起)
默认情况下,对于一个值被拷贝的变量,lambda不会改变其值。假如我们希望能改变一个被捕获的变量的值,就必须在参数列表后面加上关键字mutable。而一个引用捕获的变量则不受此限制。 

#include 

int main()
{
    int i = 10, j = 10;
    //加上mutable才可以在lambda函数中改变捕获的变量值
    auto f = [i, &j]() mutable {i = 100, j = 100;};
    i = 0, j = 0;
    f();
    //输出:0 100
    std::cout << i << \" \" << j << std::endl;
}

\"C++中的lambda表达式用法及示例_第4张图片\"


返回类型 ->

当我们需要为一个lambda定义返回类型时,需要使用尾置返回类型。返回类型若缺省,则根据函数体中的 return 语句进行推断(如果有多条return语句,需要保证类型一直,否则编译器无法自动推断)。默认情况下,如果一个lambda函数体不包含return语句,则编译器假定返回void。

#include 

int main()
{
    auto f = []() -> double {
        if (1 > 2)
            return 1;
        else
            return 2.0;
    };
    std::cout << f() << std::endl;
}

\"C++中的lambda表达式用法及示例_第5张图片\"


如果不显示指定返回类型,则int和double两种返回类型会导致推断冲突。

示例:


参考

https://blog.csdn.net/gongjianbo1992/article/details/105128849

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号