但是,C++11引入了lambda表达式后,一切都变的简单了!
1.lambda表达式
lambda表达式是一个匿名函数,用它可以非常方便的表示一个函数对象,先简单说一下lambda表达式,下面这张图表示了C++11中lambda表达式的写法Lambda表达式的引入标志,在‘[]’里面可以填入‘=’或‘&’表示该lambda表达式“捕获”(lambda表达式在一定的scope可以访问的数据)的数据时以什么方式捕获的,‘&’表示一引用的方式;‘=’表明以值传递的方式捕获,除非专门指出。
Lambda表达式的参数列表
Mutable 标识(可以没有)
异常标识(可以没有)
返回值,如果没有,可以不写
“函数”体,也就是lambda表达式需要进行的实际操作
下面看看几个lambda表达式的例子
- void print(int a){……}
- [](int a){……}
- int add(int a,int b){……}
- [](int a,int b)->int{……}
如成员变量:
double m_result;
函数:
- void foo(int a,double b)
- {
- ……
- use(m_result);
- }
- [m_result](int a,int b){……use(m_result);}
- [&m_result](int a,int b){……m_result = 12.1;……}
- double g_bb = 11.2;
- void foo1()
- {
- auto f_add = [&](int a,int b)->int{return a+b;};
- std::cout<<f_add(1,2);//3
- std::cout<<std::endl;
- double aa = 5.0;
- auto fun = [aa]()->double{return aa+3;};//此时aa不能进行赋值操作如:aa=7;
- std::cout<<fun();
- std::cout<<" aa:"<<aa<<std::endl;//8 aa:5
- auto fun2 = [&aa]()->double{aa = 7.0;return aa+3;};//此时aa以引用方式传入,可以进行赋值操作如:aa=7,同时修改aa的值;
- std::cout<<fun2();
- std::cout<<" aa:"<<aa<<std::endl;//10 aa:7
- auto fun3 = [&]()->double{aa = 8.0;g_bb = 15;return aa+3;};//此时aa可以进行赋值操作如:aa=7;,其他在作用域范围的变量都可以以引用方式调用
- std::cout<<fun3();
- std::cout<<" aa:"<<aa<<" g_bb:"<<g_bb<<std::endl;//11 aa:8
- }
- 3
- 8 aa:5
- 10 aa:7
- 11 aa:8 g_bb:15
一般也是以这种方式来写[&],简单明了。 lambda表达式先说到这后面在讲std::for_each和std::transform时会有更多例子。
2.std::for_each
std::foreach是很经典的算法,但是由于需要用到函数对象,有时候还不如直接for循环方便,例如我有个vector,我要打印出来看看里面有什么内容,经常下意识的就直接成:- std ::vector <double>v ;
- v . push_back ( 3);
- v . push_back ( 1. 666);
- v . push_back ( 4. 5);
- v . push_back ( 6. 7);
- for( std ::vector <double>::iterator i =v . begin (); i !=v . end (); ++i )
- {
- std ::cout <<*i <<",";
- }
std :: vector < double >:: iterator是多么的碍眼的。 还好,C++11把auto升了级,上面那个代码会变成
- for( autoi =v . begin (); i !=v . end (); ++i )
用std::foreach(),上面这个就变成
- std ::for_each ( v . begin (), v . end (),[ &]( double d ){ std ::cout <<d <<",";});
于是,以后凡是要遍历容器,且代码不太长,都可以使用std::for_each加lambda表达式方便实现。
C++11 for循环的新写法可以将上述写成:
for(auto b : v){ //或者for(const double& b : v)
std::cout<<b<<std::endl;
}