C++11中的匿名函数lambda怎么使用


这篇文章主要介绍“C++11中的匿名函数lambda怎么使用”,在日常操作中,相信很多人在C++11中的匿名函数lambda怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++11中的匿名函数lambda怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    官方介绍:

    C++ lambda是C++11新增的一种匿名函数的实现方式,可以在代码中直接定义一个函数对象。它的语法是通过关键字“[]”来定义的,括号里可以包含需要访问的外部变量。Lambda函数可以用于在STL算法中提供自定义的比较函数,或者作为std::function的参数。它的简洁和易用性使得在C++11中变得非常流行。

    一、lambda基础介绍

    Lambda表达式的完整声明格式如下:

    [capturelist](parameterlist)mutableexception->returntype{functionbody}
    • capture list: 用于捕获外部变量的列表,可以省略。

    • parameter list: 函数参数列表,可以省略。

    • mutable: 可选项,用于指定能否修改捕获的变量。

    • exception: 可选项,用于指定能抛出的异常。

    • return type: 可选项,用于指定返回值类型。如果省略,编译器会自动推断。

    • function body: 函数主体。

    通常情况下,一个 lambda 表达式不需要如此多的关键词,更常用的声明形式如下,只需要captures、parameters、return type、body即可:

    [captures](parameters)->return_type{body}

    有一些情况下,返回类型可以从 return 语句中推导(如 auto),则返回类型可以省略。而当 lambda 表达式没有参数的时候,用于表示参数列表的括号也是可以省略的:

    [captures]{body}//也就是[]{}

    具体的例子:

    [](){}//定义一个没有参数和返回值的lambda表达式[](inta,intb){returna+b;}//定义一个带有参数的lambda表达式[x](inta){returnx*a;}//定义一个捕获x的lambda表达式

    Lambda表达式还可以使用默认参数值,通过在参数后面使用 "= default_value"来实现。

    例如 :

    [](inta,intb=10){returna+b;}//定义一个带有默认参数值的lambda表达式

    在捕获列表中, 你可以使用&或=来捕获外部变量。

    • & 使得lambda表达式可以修改捕获的变量。

    • = 使得lambda表达式不能修改捕获的变量(默认值)。

    例如 :

    intx=10;[&x](){x++;}//定义一个可以修改x的lambda表达式[=x](){x++;}//定义一个不能修改x的lambda表达式

    Lambda表达式可以通过赋值给std::function对象或者直接调用来使用。

    例如 :

    std::function<int(int,int)>add=[](inta,intb){returna+b;};intresult=add(1,2);

    二、lambda使用例子

    2.1 STL算法中的回调函数

    STL算法如sort, for_each等需要一个可调用的对象来完成操作,这时候lambda表达式可以提供一种简洁的方式来定义这个可调用的对象。

    #include<algorithm>#include<iostream>#include<vector>intmain(){std::vector<int>v{3,1,4,1,5,9,2,6,5};std::sort(v.begin(),v.end(),[](inta,intb){returna<b;});for(intx:v)std::cout<<x<<"";std::cout<<std::endl;return0;}

    sort第三个参数可以传入一个函数,是因为 sort 使用了模板,第三个参数是一个比较函数,它是一个可以接受两个参数并返回一个bool值的函数。sort函数使用这个比较函数来确定如何排序序列中的元素。如果第三个参数省略,sort默认使用“小于”运算符进行比较。

    可以使用 std::less<int> 替换 lambda 表达式,如下所示:

    std::sort(v.begin(),v.end(),std::less<int>());

    或者你也可以定义一个比较函数来代替 lambda:

    boolmpare(inta,intb){returna<b;}std::sort(v.begin(),v.end(),mpare);

    2.2 回调函数

    在许多情况下,我们需要在某个对象的回调函数中进行某些操作,这时候lambda表达式可以提供一种简洁的方式来定义回调函数。

    #include<iostream>classButton{public:voidsetOnClick(std::function<void()>onClick){m_onClick=onClick;}voidclick(){m_onClick();}private:std::function<void()>m_onClick;};intmain(){Buttonbtn;btn.setOnClick([](){std::cout<<"Buttonclicked"<<std::endl;});btn.click();return0;}

    "setOnClick" 函数接收一个 std::function<void()> 类型的参数,并将其存储在类的私有成员变量 "m_onClick" 中。std::function 是一种 C++11 标准库中的类型,它可以存储可调用的对象,如函数指针、函数对象、Lambda 表达式等,这段代码它存了一个void()的类型的调用。

    "click" 函数调用了 "m_onClick",也就是之前设置的 std::function<void()> 类型的回调函数。

    在 main 函数中,一个 Button 对象 "btn" 被创建并初始化。 然后调用 btn.setOnClick({std::cout << "Button clicked" << std::endl;}); 这个方法,将一个 lambda 表达式作为参数设置给 m_onClick。 最后调用 btn.click(); 触发了上面设置的 lambda 表达式。

    2.3 多线程编程

    在多线程编程中,我们需要启动一个新线程来执行某些操作,这时候lambda表达式可以提供一种简洁的方式来定义线程的操作。

    #include<iostream>#include<thread>intmain(){intx=10;std::threadt([&x](){x++;});t.join();std::cout<<x<<std::endl;return0;}

    这段代码使用了 C++11 的线程库 std::thread。在 main 函数中,一个 int 类型的变量 x 被赋值为 10。然后创建了一个 std::thread 对象 "t",该对象的构造函数接收了一个 lambda 表达式,在这个 lambda 表达式中,变量 x 的值被自增。

    到此,关于“C++11中的匿名函数lambda怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注主机评测网网站,小编会继续努力为大家带来更多实用的文章!


    上一篇:Java中Maven打包方式和执行jar的方法是什么

    下一篇:antd?vue?v-decorator的取值与赋值问题怎么解决


    Copyright © 2002-2019 测速网 www.inhv.cn 皖ICP备2023010105号
    测速城市 测速地区 测速街道 网速测试城市 网速测试地区 网速测试街道
    温馨提示:部分文章图片数据来源与网络,仅供参考!版权归原作者所有,如有侵权请联系删除!

    热门搜索 城市网站建设 地区网站制作 街道网页设计 大写数字 热点城市 热点地区 热点街道 热点时间 房贷计算器