标签:
[ capture-list ] ( params ) mutable(optional) exception attribute -> ret { body } (1)
[ capture-list ] ( params ) -> ret { body } (2)
[ capture-list ] ( params ) { body } (3)
[ capture-list ] { body } (4)
上述四种表达式的定义,第一种是Full declaration
;第二种是常用模式;第三种是忽略返回值的形式(函数体只是一个return
语句,则可以自推断返回类型,否则是void
);第四种是忽略返回值和参数列表的形式。
下面就是忽略返回值和函数列表的形式(4):
auto f = []{return 42; };
cout << f() << endl;
带有参数列表的形式(3):
auto f = [](const string &a, const string &b){return a.size() < b.size(); };
cout << f("whoareyou", "whereareyou") << endl;
使用捕获列表(只是值捕获,更复杂的形式在后面介绍):
int size = 4;
auto f = [size](const string &str){return str.size() > size; };
cout << f("who") << endl; // false
如果是引用捕获:
int size = 4;
auto f = [&size](const string &str){return str.size() > size; };
cout << f("who") << endl;
size = 2;
cout << f("who") << endl;
当使用引用方式捕获一个变量时,必须保证在
lambda
表达式执行时变量是存在的。
捕获列表可以是如下形式:
[a,&b] where a is captured by value and b is captured by reference.
[this] captures the this pointer by value
[&] captures all automatic variables odr-used in the body of the lambda by reference
[=] captures all automatic variables odr-used in the body of the lambda by value
[] captures nothing
mutable
。 int size = 4;
auto f = [size](const string &str) mutable
{
size--;
cout << size << endl;
return str.size() > size;
};
cout << f("wsho") << endl; // 先输出 3, 然后是 true
cout << f("o") << endl; // 先输出2, 然后是 false
下面解释上述输出的原因:
上述lambda
表达式,编译器将其翻译成一个未命名类的未名名对象。
对上述表达式,将产生类似于下面的类:
class comp
{
comp(int sz):size(sz){}
bool operator()(const string &s) const
{
size--;
cout << size << endl;
return str.size() > size;
}
private:
int size;
}
这也解释了上述由3变为2的过程。
严格来说上述表达式的函数体中包含多行除return
以外的语句,返回类型是void
的。但是却仍然正确,只能说是不符合标准但却被编译器(MSVC
、GCC
)接受的行为。
int size = 4;
auto f = [size](const string &str) mutable ->bool
{
size--;
cout << size << endl;
return str.size() > size;
};
cout << f("wsho") << endl;
cout << f("o") << endl;
标签:
原文地址:http://blog.csdn.net/yapian8/article/details/45099291