lambda表达式

资料参考


       http://www.jb51.net/article/56147.htm

       https://msdn.microsoft.com/zh-cn/library/dd293603.aspx

匿名函数


       匿名函数是一些拥有函数体,但没有函数名的函数。lambda表达式是一种与匿名函数相关的编程技术,但需要说明的是lambda表达式得到的不是一个匿名函数,而是一个函数对象。msdn:lambda隐式定义函数对象类并构造该类类型的函数对象

lambda语法


       语法:[capture-clause] (parameter-list) mutable throw() -> return-type { lambda-body }

      

       1. capture-clause也叫做lambda-introducer在lambda中你必须要决定局部变量和函数参数的捕获方式:值传递、引用传递或者根本不捕获。捕获列表有如下几种形式:

       • [var]    - 表示值传递方式捕捉变量var;
       [=]      - 表示值传递方式捕捉所有父作用域的变量(包括this);
       [&var] - 表示引用传递捕捉变量var;
       [&]      - 表示引用传递方式捕捉所有父作用域的变量(包括this);
       [this]   - 表示值传递方式捕捉当前的this指针。

       2. 参数列表。如果参数列表为空,并且表达式不包含throw()返回类型mutable的情况下,可以省略空括号。

       3. mutable修饰符。默认情况下,lambda表达式的调用总是const-by-value,mutable可以取消其常量性。

       4. throw异常标识。可以使用throw()异常规范来指示Lambda表达式不会引发任何异常。 如果lambda表达式声明throw()异常规范且lambda体引发异常,visual c++编译器将生成警告c4297

       5. 返回类型如果lambda体仅包含一个返回语句或其表达式不返回值,则可以省略lambda表达式的返回类型部分。如果lambda体包含单个返回语句,编译器将从返回表达式的类型推导返回类型。 否则,编译器会将返回类型推导为void 

       6. lambda体。lambda体不仅可包含普通函数主体可包含的任何内容,还可以访问它从封闭范围中捕获的变量。

lambda举例


       1. 将数组按照元素的绝对值大小进行排序。

#include <cmath>
#include <algorithm>

template <class T>
void abssort(T *pArray, unsigned uLength)
{
    std::sort(pArray, pArray + uLength,
        // lambda expression begins
        [](T a, T b) { return (std::abs(a) < std::abs(b)); }
        // lambda expression ends
    );
}

        2. 闭包特性。

#include <vector>
#include <algorithm>

int main(int argc, char* argv[])
{
    int nTotalScores = 0;
    std::vector<int> scores{ 10, 20, 30, 40 };

    std::for_each(scores.begin(), scores.end(),
        // lambda expression begins
        [&nTotalScores](int v){ nTotalScores += v; }
        // lambda expression ends
    );

    return 0;
}

 

posted @ 2015-04-30 16:30  碎语心弦  阅读(381)  评论(0编辑  收藏  举报