c++ Lambda表达式_1

C++11允许程序员通过Lambda表达式定义和创建匿名的函数。本篇文章通过几个例子来直观的描述Lambda表达式。

Lambda表达式初体验

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
void print_it(int i) {
    cout<<":"<<i<<":";
}
int main() {
    list<int> int_list={1,2,3,4,5,6,7,8,9,0};
    cout<<"without use lambda"<<endl;
    for_each(int_list.begin(),int_list.end(),print_it);
    cout<<endl;
    cout<<"use lambda"<<endl;
    for_each(int_list.begin(),int_list.end(),[](int i){ cout<<":"<<i<<":";});
    cout<<endl;
    return 0;
 }

上面这几行代码的作用是遍历输出容器int_list中的所有元素,并且利用到了STLfor_eachfor_each的作用可以大家可以自己查询一下,本章的重点是讲解Lambda表示式。
在没有利用Lambda表达式时,我们需要定义一个函数print_it。为了使代码更加的简洁和优雅,利用Lambda表达式可以只用一行代码就完成遍历int_list中的所有元素的功能:

for_each(int_list.begin(),int_list.end(),[](int i){ cout<<":"<<i<<":";});

Lambda表达式的例子二

在上一个例子中,通过用

for_each(int_list.begin(),int_list.end(),[](int i){ cout<<":"<<i<<":";});

替换

for_each(int_list.begin(),int_list.end(),print_it);

达到用一行代码完成遍历容器int_list中的所有元素。比较这两行代码,可以看出Lambda表达式替换掉了函数名print_it。由此,是否可以推测Lambda表达式的功能:Lambda表达式本质上创建了一个类似与函数对象或者函数指针的东西
接下来可以写几行代码验证一下:

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

int main() {
    auto func1=[](int i){cout<<":"<<i<<":";};
    func1(24);
    cout<<endl;
    [](int i){cout<<":"<<i<<":";}(34);
    cout<<endl;
    auto func2 = [](){ cout<<"hello lambda!"<<endl;};
    func2();
    return 0;
}

这个例子将输出:
这里写图片描述
所以大致可以证明,我的猜想是正确的。

Lambda表达式的基本概念

一个Lambada表达式的基本结构如下:

[capture list](parameter list) {function body}
[捕捉外部变量列表](参数列表)(函数体)

在Lambada表达式中,参数列表和函数体和普通的函数是一样的。但是,在Lambda表达式子中函数体的返回值类型需要注意。如果没有return语句则认为返回类型为空。如果有return语句则返回类型和返回的值是一样的。

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

int main() {
    [](){cout<<"Hello from trival lambda!"<<endl;}(); // return void type
    //cout<<[](){cout<<"Hello from trival lambda!"<<endl;}(); // compile error
    if([](int i, int j){ return 2*j==j;}(12,24)) // return bool type
        cout<<"It is true!"<<endl;
    else
        cout<<"It is false!"<<endl;
    return 0;
}

运行结果如下:
这里写图片描述
当然,C++11还允许程序员指定Lambada表达式的返回类型,其详细的代码如下:

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

int main() {
    cout<<"This is lambda returns "<<
                                   [](int x,int y)->int{
                                       if(x>5)
                                           return x+y;
                                       else if (y<2)
                                           return x+y;
                                       else
                                           return x*y;
                                   }(4,3)<<endl;
    cout<<"This is lambda returns "<<
                                   [](double x, double y)->int {
                                       return x+y;
                                   }(3.14,2.7)<<endl; // output is 5 !!!

    return 0;
}

在上面这个例子中的输出:
这里写图片描述
其中,

    cout<<"This is lambda returns "<<
                                   [](double x, double y)->int {
                                       return x+y;
                                   }(3.14,2.7)<<endl; // output is 5 !!!

指定Lambda表达式的返回类型是int,所以,虽然3.14+2.7=5.84,但是通过强制类型转换,变成了5

Lambda 捕捉程序的上下文

Lambda表达式可以使用可见范围内的外部变量,但是必须明确那些外部变量可以被Lambda表达式使用。Lambda表达式应用外部变量的过程被称为”变量捕捉“。Lambda表达式提供一下几种值的捕捉方式:
1. 值捕捉: 允许对变量进行读操作,不允许修改变量的值
2. 引用捕捉:允许修改变量的值
3. 隐式捕捉 :1、[=]对所有变量进行值捕捉;2、[&]对所有变量进行引用捕捉。

#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

int main() {
    int var_1 = 123;
    int var_2 = 321;
    [var_1]()  {cout<<var_1<<endl;}(); // var_1 are captured by value 
    [&var_1] () { cout<<++var_1<<endl;}(); // var_1 are captured by reference
    [=](){ cout<<var_1<<" "<<var_2<<endl;}(); //  all variables are captured by value
    [&](){ cout<<++var_1<<" "<<++var_2<<endl;}(); // all variables are captured by reference
    return 0;
}

上述代码的输出的结果是:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/u012836279/article/details/80168500