首页 > 代码库 > C++11 lambda表达式学习

C++11 lambda表达式学习

lambda表达式是函数式编程的基础。咱对于函数式编程也没有足够的理解,因此这里不敢胡言乱语,有兴趣的可以自己查找相关资料看下。这里只是介绍C++11中的lambda表达式自己的认识。这里有参考文档http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2927.pdf

 给出两个例子,可以看出lambda表达式的写法

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

[](int x, int y) -> int { int z = x + y; return z + x; } //表明返回值类型是int型

一个lambda表达式很类似于普通的函数定义的写法,区别在于三点,一是没有函数名(你也可以认为函数名是[]),二是这个函数没有普通函数那样的返回值类型,返回值类型的写法,即在参数列表与函数定义之间以箭头写明,三是在参数列表之前有一个[] (其实这里还可能有更多的形式)


lambda表达式的语法如下所示:
[捕捉快](参数) 异常 -> 返回值类型 {主体}
通过lambda表达式这项功能可以编写内嵌的匿名函数,而不必编写独立函数和函数对象,使得代码更容易理解。
 
下面引用别人的例子将逐步演示如何使用lambda表达式:
范例一:
[]{std::cout<<"Hello from Lambda!"<<std::endl;}();
输出如下所示:
Hello from Lambda
在控制台输出Hello from Lambda,尾部的括号使该表达式可立即执行。
 
范例二:
std::string result=[](const std::string& str)->std::string{return "Hello from "+str;}("second Lambda");
std::cout<<result<<std::endl;
输出如下所示:
Hello from second Lambda
该lambda表达式接受一个string参数并返回一个string,结果保存在变量result中,尾部的括号使得该表达式立即执行。
 
范例三:
auto fn=[](const std::string& str) {return "Hello from "+str;};
std::cout<<fn("call 1")<<std::endl;
std::cout<<fn("call 2")<<std::endl;
输出如下所示:
Hello from call 1
Hello from call 2
此处保存指向lambda表达式的指针,并且通过函数指针执行该表达式。
 
范例四:(STL与lambda)
#include <iostream>
#include <algorithm>
#include <vector>
 
auto main(int argc, char** argv) -> int
{
    std::vector<int> vec={1, 2, 3, 4, 5, 6, 7, 8, 9};
    int value=http://www.mamicode.com/3;
    int cnt=std::count_if(vec.cbegin(), vec.cend(), [=](int i){return i>value;});
    std::cout<<"Found "<<cnt<<" values > "<<value<<std::endl;
 
    return 0;
}
输出如下所示:
Found 6 values > 3
通过count_if算法计算vector中满足特定条件的元素个数,lambda表达式的形式给出了条件,注意表达式中的=,等号表示通过值捕捉所在作用域的变量,这个例子中捕捉的是value的值。前面的例子[]为空,即捕捉块为空,那么在lambda表达式的主体body内就无法访问变量了。以下是关于捕捉块的详细介绍:
[=]通过值捕捉所有变量
[&]通过引用捕捉所有变量
[value]通过值捕捉value,不捕捉其它变量
[&value]通过引用捕捉value,不捕捉其它变量
[=, &value]默认通过值捕捉,变量value例外,通过引用捕捉
[&, value]默认通过引用捕捉,变量value例外,通过值捕捉
 
范例五:(STL与lambda结合)
#include <iostream>
#include <algorithm>
#include <vector>
 
auto main(int argc, char** argv) -> int
{
    std::vector<int> vec={11, 22, 33, 44};
    int index=0;
    for_each(vec.begin(), vec.end(), \
             [&index](int i){std::cout<<"Value "<<(index++) \
             <<": "<<i<<std::endl;});
 
    return 0;
}
通过for_each算法可以对给定范围中的所有元素执行特定操作,调用lambda表达式,并将这个值作为参数传递给lambda表达式。
 范例程序差不多了,在C++11中,官方似乎一直鼓励大家用lambda表达式,而不是函数对象,lambda表达式更易于使用和理解。

C++中lambda表达式与传统的函数相比有什么优势?

   lambda表达式你可以理解为匿名函数,比如你代码里有一些小函数,而这些函数一般只被调用一次(比如函数指针),这时你就可以用lambda表达式替代他们,这样代码看起来更简洁些,用起来也方便。

 

C++11 lambda表达式学习