C++11的 lambda函数(匿名函数)

初识 lambda 函数 (匿名函数)

#include <iostream>
using namespace std;

int main()
{
    int girls = 3, boys = 4;
    auto totalChild = [](int x, int y )->int{return x+y;};

    cout<< totalChild(girls, boys)<<endl;
    return 0;
}

 

我们定义了 lambda 函数,该函数接受2个参数(int x, inty),并且返回其和。 直观地看,lambda 函数跟普通函数相比不需要定义函数名,取而代之的多了一对方括号 ( [] ) 此外,lambda 函数还采用了追踪返回类型的方式声明其返回值。

lambda 函数的语法定义如下

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

其中,

  • [capture]:捕捉列表。捕捉列表总是出现在lambda函数的开始处。事实上,[]是lambda引出符。 编译器根据该引出符判断接下来的代码是否是lambda函数。 捕捉列表能够捕捉上下文中的变量以供lambda函数使用。

  • (parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连通括号 () 一起省略。

  • mutable:mutable修饰符。默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。 在使用该修饰符时,参数列表不可省略(即使参数为空)。

  • ->return-type:返回类型。用追踪返回类型形式声明函数的返回类型。 出于方便,不需要返回值的时候,也可以连同符号 -> 一起省略。 此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。

  • {statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

在lambda函数的定义中,参数列表和返还类型都是可选的部分。 捕捉列表可能为空。极端情况下,C++11中最为简略的lambda函数只需要声明为

[]{};

各种各样的 lambda 函数

int main(){
    []{};           // 最简lambda函数
    int a = 3;
    int b = 4;
    [=] { return a + b;};       // 省略了参数列表与返回类型,返回类型由编译器推断为int
    auto fun1 = [&](int c) { b = a + c; };  // 省略了返回类型,无返回值
    auto fun2 = [=, &b](int c)->int { return b += a + c; };     // 各部分都很完整
}

 

使用捕捉列表改写前面的例子:

int main() {
    int boys = 4, int girls = 3;
    auto totalChild = [girls, &boys]()->int{ return girls + boys; }; 
    return totalChild();
}

 

捕捉列表有如下几种形式

  • [var]表示值传递方式捕捉变量 var

  • [=]表示值传递方式捕捉所有父作用域的变量( 包括 this )

  • [&var]表示引用传递捕捉变量 var

  • [&]表示引用传递捕捉所有父作用域的变量( 包括 this )

  • [this]表示值传递方式捕捉当前的 this 指针

通过一些组合,捕捉列表可以表示更复杂的意思,比如:

  • [=,&a,&b]

  • [&,a,this]

不过,值得注意的是,捕捉列表不允许变量重复传递。下面的例子就是典型的重复,会导致编译时期的错误。

  • [=,a] 这里 "=" 已经以值传递方式捕捉了所有变量,捕捉a重复

  • [&,&this]这里 "&" 已经以引用传递方式捕捉了所有变量,再捕捉 this 也是一种重复。

通过 [=] 来声明捕捉列表,进而对 totalChild 书写上的进一步简化

int main() {
    int boys = 4, int girls = 3;
    auto totalChild = [=]()->int{ return girls + boys; }; 
    return totalChild();
}

 

 

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
//从大到小 排序
bool cmp321(int A, int B)
{
    return A>B;
}
//从小到大 排序
bool cmp123(int A, int B)
{
    return A<B;
}

// 用匿名函数 来替代 cmp比较函数
int main() { vector<int> vec={10,9,8,8,7,7,7,5,3,1};//从大到小排序 auto upIt = upper_bound(vec.begin(), vec.end(),7, [](int A, int B){return A>B;}); auto lowIt = lower_bound(vec.begin(), vec.end(),7, [](int A, int B){return A>B;}); cout <<"-----finished -----"<<endl; return 0; } // g++ testFun1.cpp --std=c++11

 

 

 

posted @ 2020-12-13 23:52  He_LiangLiang  阅读(161)  评论(0编辑  收藏  举报