C++ox 之 lambda

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





你可能感兴趣的:(C++ox 之 lambda)