Lambda是c++11中最重要的新特性之一,cppreference.com是这样定义的:
an unnamed function object capable of capturing variables in scope。即可以使用临时局部变量的匿名函数。
Lambda的完整语法如下:
[ capture ] ( params ) mutable(optional) exception attribute -> ret { body }
除了[ capture ]和{ body }是必需的,其他都可以省略。
Capture
Capture定义了lambda需要使用的同一作用域的局部变量,全局变量和外部变量不需要捕获就可以直接使用。
[] 不捕获任何局部变量
[&] 引用捕获所有局部变量
[=] 值捕获所有局部变量
[=, &foo] 除了foo引用捕获,其他局部变量全部值捕获
[bar] 只值捕获bar
[this] 捕获宿主对象指针。
最主要的区别是值捕获和引用捕获
int n =3; auto f1 = [=n](string &s) {return s.size()>n;} auto f2 = [&n](string &s) {return s.size()n;} string name = “kian”; n++; f1(name); //s.size>3? return true, f2(name); // s.size>4? return false
Return type:
如果没有return语句,那么编译器会推断return void,
[](string &s) {cout<< s.size()>3;}
只有一个return语句,编译器也可以根据返回值推断出返回类型,下面两种方法是等价的
[](string &s) {return s.size()>3;} [](string &s) bool {return s.size()>3;}
如果函数体内有多个return语句,需要用尾置返回类型->明确指定,
[](string &s){if s.size()>3) return true; else return false;} // wrong [](string &s) –>bool {if s.size()>3) return true; else return false;} // right
Exception
下面lambda表示不抛出异常:
[](string &s) throw() -> bool {return s.size()>3;}
Mutable
如果需要修改捕获的值,则需要mutable
int n =3; auto f1 = [n](string &s)mutable {n++; return s.size()>n;}
lambda的实现
编译器会将Lambda表达式转换为函数对象,比如
[](string &s){return s.size()>3;}
等价于
class greater { public: bool operator()(string &s ) const {return s.size()>3;} };
如果capture list有值捕获参数的话,将作为函数对象的私有数据保存,引用捕获可以直接使用引用变量,不需要缓存。
[n](string &s){return s.size() > n;}
等价于
class greater { public: bool operator()(string &s ) const {return s.size()>n;} private: int n; };
Reference:
http://zh.cppreference.com/w/cpp/language/lambda
http://www.cprogramming.com/c++11/c++11-lambda-closures.html