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; }