Lambda表达式的引入标志,在‘[]’里面可以填入‘=’或‘&’表示该lambda表达式“捕获”(lambda表达式在一定的scope可以访问的数据)的数据时以什么方式捕获的,‘&’表示一引用的方式;‘=’表明以值传递的方式捕获,除非专门指出。
Lambda表达式的参数列表
Mutable 标识(可以没有)
异常标识(可以没有)
返回值,如果没有,可以不写
“函数”体,也就是lambda表达式需要进行的实际操作
下面看看几个lambda表达式的例子
void print(int a){……}上面函数lambda表达式为:
[](int a){……}上面这个是无返回值的例子,下面这个是有返回值的例子
int add(int a,int b){……}上面函数lambda表达式为:
[](int a,int b)->int{……}当需要引入其他变量的时候,如有个类的成员变量需要引用或者函数局部变量这种情况下可以显示声明需要引入的变量
void foo(int a,double b) { …… use(m_result); }其lambda表达式可以表示为
[m_result](int a,int b){……use(m_result);}如果lambda表达式需要修改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
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 <<","; }
for( autoi =v . begin (); i !=v . end (); ++i )
std ::for_each ( v . begin (), v . end (),[ &]( double d ){ std ::cout <<d <<",";});
template<typename Container> void printElement(Container& v) { std::cout<<"("; for(auto i = v.begin();i != v.end();++i) { std::cout<<*i; if(i != v.end() - 1) std::cout<<","; } std::cout<<")"; std::cout<<std::endl; }
template <class InputIterator, class OutputIterator, class UnaryOperation> OutputIterator transform (InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op);
template <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation>; OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op);原理如下图所示:
如需要求序列a的log,结果存入c
//求a的log存入c a.clear();b.clear();c.clear(); for(auto i(1);i<10;++i){ a.push_back(i); } std::transform(a.begin(),a.end(),std::back_inserter(c),[](double d)->double{return log(d);}); std::cout<<"a:"; printElement(a);// std::cout<<"c:"; printElement(c);//(0,0.693147,1.09861,1.38629,1.60944,1.79176,1.94591,2.07944,2.19722)
std::cout<<"a=log(a):"<<std::endl<<"a:"; printElement(a); std::transform(a.begin(),a.end(),a.begin(),[](double d)->double{return log(d);}); std::cout<<"after a:"; printElement(a);//(0,0.693147,1.09861,1.38629,1.60944,1.79176,1.94591,2.07944,2.19722)输出:
a=log(a): a:(1,2,3,4,5,6,7,8,9) after a:(0,0.693147,1.09861,1.38629,1.60944,1.79176,1.94591,2.07944,2.19722)
std::cout<<"a=log(a):"<<std::endl<<"a:"; printElement(a); std::for_each(a.begin(),a.end(),[](double& d){d = log(d);}); std::cout<<"after a:"; printElement(a);//(0,0.693147,1.09861,1.38629,1.60944,1.79176,1.94591,2.07944,2.19722)
a=log(a): a:(1,2,3,4,5,6,7,8,9) after a:(0,0.693147,1.09861,1.38629,1.60944,1.79176,1.94591,2.07944,2.19722)
std ::vector <double>v , w , u ; v . push_back ( 3); v . push_back ( 1.666); v . push_back ( 4.5); v . push_back ( 6.7); w . push_back ( 3); w . push_back ( 1.666); w . push_back ( 4.5); w . push_back ( 6.7); for( autoi =v . begin (), j =w . begin (), k =u . begin (); i !=v . end (), j !=w . end (), k !=u . end ();++i ,++j ,++k ) { *k =sin (*i )+*j ; }
std ::transform ( v . begin (), v . end (), w . begin (), u . begin () ,[&]( double a , double b )->double{ return sin ( a )+b ; } );
a.clear(); b.clear(); c.clear(); for(int i(1);i<10;++i) { a.push_back(i); b.push_back(i*10); } std::cout<<"calc c=a+b:"<<std::endl<<"a:"; printElement(a); std::cout<<"b:"; printElement(b); std::transform(a.begin(),a.end(),b.begin(),std::back_inserter(c),std::plus<double>()); std::cout<<"calc c=a+b -> c:"; printElement(c);
calc c=a+b: a:(1,2,3,4,5,6,7,8,9) b:(10,20,30,40,50,60,70,80,90) calc c=a+b -> c:(11,22,33,44,55,66,77,88,99)
代码:
#include <iostream> #include <functional> #include <algorithm> #include <vector> #include <iterator> #include "math.h" 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 } template<typename Container> void printElement(Container& v) { std::cout<<"("; for(auto i = v.begin();i != v.end();++i) { std::cout<<*i; if(i != v.end() - 1) std::cout<<","; } std::cout<<")"; std::cout<<std::endl; } int main() { foo1(); std::vector<double> a,b,c; a.push_back(3); a.push_back(1.666); a.push_back(4.5); a.push_back(6.7); b.push_back(3); b.push_back(1.666); b.push_back(4.5); b.push_back(6.7); for ( std :: vector < double >:: iterator i = a . begin (); i != a . end ();++ i ) { std::cout<<*i<<",";//3,1.666,4.5,6.7, } std::cout<<std::endl; std::for_each(a.begin(),a.end(),[&](double d){std::cout<<d<<",";});//3,1.666,4.5,6.7, std::cout<<std::endl; c.resize(a.size()); for (auto i=a.begin(),j =b.begin(),k = c.begin(); i!=a.end (),j!=b.end(),k!=c.end();++i,++j,++k) { *k = sin(*i)+*j; } std::transform(a.begin(),a.end(),b.begin(),c.begin() ,[&](double i,double j)->double{return sin(i)+j;}); printElement(c);//(3.14112,2.66147,3.52247,7.10485) a.clear();b.clear();c.clear(); for(auto i(1);i<10;++i){ a.push_back(i); } //求a的log存入c std::cout<<"c=log(a):"<<std::endl<<"a:"; printElement(a); std::transform(a.begin(),a.end(),std::back_inserter(c),[](double d)->double{return log(d);}); std::cout<<"c:"; printElement(c);//(0,0.693147,1.09861,1.38629,1.60944,1.79176,1.94591,2.07944,2.19722) b = a; std::cout<<"a=log(a):"<<std::endl<<"a:"; printElement(a); std::transform(a.begin(),a.end(),a.begin(),[](double d)->double{return log(d);}); std::cout<<"after a:"; printElement(a);//(0,0.693147,1.09861,1.38629,1.60944,1.79176,1.94591,2.07944,2.19722) a = b; std::cout<<"a=log(a):"<<std::endl<<"a:"; printElement(a); std::for_each(a.begin(),a.end(),[](double& d){d = log(d);}); std::cout<<"after a:"; printElement(a);//(0,0.693147,1.09861,1.38629,1.60944,1.79176,1.94591,2.07944,2.19722) a.clear(); b.clear(); c.clear(); for(int i(1);i<10;++i) { a.push_back(i); b.push_back(i*10); } std::cout<<"calc c=a+b:"<<std::endl<<"a:"; printElement(a); std::cout<<"b:"; printElement(b); std::transform(a.begin(),a.end(),b.begin(),std::back_inserter(c),std::plus<double>()); std::cout<<"calc c=a+b -> c:"; printElement(c); return 0; }
#define INPUT #define OUTPUT namespace Array { /// /// \brief 加一个常数的函数对象,类似于std::plus<T>(),不过此函数对象是用于对一个常数进行加法运算 /// template <class T> struct plus_const : std::binary_function <T,T,T> { plus_const(const T& data){m_data = data;} T operator() (const T& x) const {return x+m_data;} T m_data; }; /// /// \brief 序列加法运算,用于序列加上单一一个值 /// \param begin 序列迭代器的起始 /// \param end 序列迭代器的结尾 /// \param beAddData 需要进行加法运算的值 /// \note 此操作会直接修改原有序列值 /// template<typename T,typename IT> void add(INPUT IT begin,INPUT IT end,T beAddData) { std::transform(begin,end,begin,plus_const<T>(beAddData)); } /// /// \brief 序列加法运算,两个等长序列相加 /// \param begin_addfont “加数”序列迭代器的起始 /// \param end_addfont “加数”序列迭代器的结尾 /// \param begin_addend “被加数”序列迭代器的起始 /// \param begin_res 用于存放结果的序列的起始地址 /// template<typename T,typename IT> void add(INPUT IT begin_addfont,INPUT IT end_addfont,IT begin_addend,IT begin_res) { std::transform(begin_addfont,end_addfont,begin_addend,begin_res ,std::plus<T>()); } /// /// \brief 序列减法运算,两个等长序列相减 /// \param begin_addfont “加数”序列迭代器的起始 /// \param end_addfont “加数”序列迭代器的结尾 /// \param begin_addend “被加数”序列迭代器的起始 /// \param begin_res 用于存放结果的序列的起始地址 /// template<typename T,typename IT> void minus(INPUT IT begin_minusfont,INPUT IT end_minusfont,IT begin_minusend,IT begin_res) { std::transform(begin_minusfont,end_minusfont,begin_minusend,begin_res ,std::minus<T>()); } /// /// \brief 序列减法运算,用于序列减去单一一个值 /// \param begin 序列迭代器的起始 /// \param end 序列迭代器的结尾 /// \param beAddData 需要进行减法运算的值 /// \note 此操作会直接修改原有序列值 /// template<typename T,typename IT> void minus(INPUT IT begin,INPUT IT end,T beMinusData) { std::transform(begin,end,begin,plus_const<T>(-beMinusData)); } …… }
C++11 lambda表达式在for_each和transform算法下的使用
原文:http://blog.csdn.net/czyt1988/article/details/43636473