http://www.cnblogs.com/allenlooplee/archive/2012/07/03/2574119.html
今天看了博文,之前对于lambda的理解比较粗陋,今天再学习一下。
不得不说我是一个极为懒惰的人,因此,只有代码了。。。。
#include <iostream> #include <vector> #include <algorithm>//for generate using namespace std; /* * the example for using sample lambda */ int randNum(vector<int>&numbers) { generate(numbers.begin(), numbers.end(), []{//使用lambda,[]是Lambda的捕获子句,也是引出Lambda的语法 return rand() % 100; } ); return 0; } template<typename T> void debugVector(const vector<T> &numbers) { for (auto it = numbers.begin(); it != numbers.end(); ++it) { cout<<*it<<"\t"; } cout<<endl; } /* * using varibales */ int oddCount(const vector<int> &vec) { int nCnt = 0; for_each(vec.begin(), vec.end(), [&nCnt](int value){//lambda使用local变量 /* * C++要求我们在Lambda的捕获子句里显式指定想要捕获的变量 * C++还要求我们指定这些变量的传递方式,可以选择的传递:按值传递和按引用传递. * 如果你希望按引用传递捕获当前上下文的所有变量,可以把捕获子句写成[&]; * 如果你希望按值传递捕获当前上下文的所有变量,可以把捕获子句写成[=]。 * 如果你希望把按引用传递设为默认的传递方式,同时指定个别变量按值传递,可以把捕获子句写成[&,a,b]; * 同理;如果默认的传递方式是按值传递,个别变量按引用传递,可以把捕获子句写成[=,&a, &b]。 * 值得提醒的是,像[&, a, &b]和[=, &a,b]这些写法是无效的, * 因为默认的传递方式均已覆盖b变量,无需单独指定,有效的写法应该是[&,a]和[=, &a]。 */ if (value % 2) { ++nCnt; } } ); return nCnt; } //pass in the reference int arithmeticSequence(vector<int> &vec) { int nStep = 2; int nBg = -2; generate(vec.begin(), vec.end(), [&nBg, nStep]{ return (nBg += nStep); } ); cout<<nBg<<endl; return 0; } int arithmeticSequenceExt(vector<int> &vec) { int nStep = 2; int nBg = -2; /* * 如果我们加上mutable声明,参数列表就不能省略了,即使里面没有包含任何参数 * mutable声明使得我们可以在Lambda的函数体修改按值传递的变量, * 但这些修改对Lambda以外的世界是不可见的,有趣的是,这些修改在Lambda的多次调用之间是共享的。 * 换句话说,代码4的generate函数调用了10次Lambda, * 前一次调用时对i变量的修改结果可以在后一次调用时访问得到。 * 这听起来就像有个对象,i变量是它的成员字段,而Lambda则是它的成员函数, * 事实上,======Lambda是函数对象(FunctionObject)的语法糖,================ * Lambda最终会被转换成Functor类 */ generate(vec.begin(), vec.end(), [nBg, nStep]()mutable{ return (nBg += nStep); } ); cout<<nBg<<endl; return 0; } //===============how to definition a lambda======================== //1st: using auto //void lambdaAutoDefine() //{ // auto f = [](int x, int y){ // return x+y; // }; // cout<<f(1, 2)<<endl; //} // ////2nd: using function template ////2nd: using function template //void lambdaTemplateDefine() //{ // function<int (int , int)> f; // cout<< f(1, 2)<<endl; //} // ////3rd: using template function declaration // template<typename Fn> //void LambdaTemplateFnDefine(Fn f) //{ // cout<<f(1, 2)<<endl; //} //==============================捕获变量的值确定时间============================== //因为按值传递在声明Lambda的那一刻就已经确定变量的值了, //无论之后外面怎么修改,里面只能访问到声明时传过来的版本 int testVarible() { int x = 1, y = 2; auto f = [x, &y]{return x+y;}; x = 3; y = 4; cout<<f()<<endl; return 0; } //==============================the definition for return value============================== /* 有两种情况可以在声明Lambda时省略返回值类型: 1. 函数体只包含一条返回语句 2. Lambda没有返回值 当需要加上返回值的类型时,必须把它放在参数列表后面,并且在返回值类型前面加上"->"符号 */ int testReturnValue() { auto f = [](int x, int y) -> std::string{ return std::string("hello word"); }; cout<<f(1, 2)<<endl; return 0; } int main() { vector<int>numbers(10); randNum(numbers); debugVector(numbers); cout<<oddCount(numbers)<<endl; arithmeticSequence(numbers); debugVector(numbers); arithmeticSequenceExt(numbers); debugVector(numbers); testVarible(); testReturnValue(); return 0; }
详细和完整的代码请移步:
https://github.com/luyao/cplusplus0xLeaning