迷彩 潜伏 隐蔽 伪装
分类: C/C++
2013-02-07 19:43:33
原文地址:泛型lambda表达式 作者:jexpo
第10章中关于lambda的内容
函数式编程很火热,未来应该会有很大的发展,虽然目前还没有完全搞明白它的切入点。
很多泛型算法需要我们传入一个callable object充当谓词,可以是函数或函数指针,重载了()的某对象,再或是一个lambda表达式。
SBL说简单点可以理解为一个无名的内联函数(unnamed,inline),语法格式:
[capture list] (parameter list) -> return type { function body }
不同于函数,其可以在函数中嵌套定义,现用。书中所言c++中lambda表达式必须使用这种trailing return的形式说明返回类型,不过很多时候返回类型可以省略,那就取决于函数体内的return语句。当然没有return就是个void。书中意思要么是一条return,要么是多条语句,实际多条语句+return也编的过,这
If the function body is just a return statement, the return type is inferred from the type of the expression that is returned. Otherwise, the return type is void.
auto f = [] { return 42; };
这是一个简单L表达式,f是其的名字,省略了返回类型说明和参数列表,调用f(),得到的返回值是42.
stable_sort(words.begin(), words.end(), [](const string &a, const string &b) { return a.size() < b.size();});当函数参数不一定要传有名的(自我理解),[]为空,说明不需要从上下文context中“导入数据使用”。
比如一个一元的L判断一个string的长度是否小于调用其函数的某局部变量length(静态变量就不用了),那么就可以把length放入[]
[length](const string &a) { return a.size() >= length; };[]内多个元素的话,像参数一样使用逗号分割。调用者外部就可见的名字也不用放入[],例如cout等等。
[]中的变量传入或函数体内的变量创建就像类对象一样,在声明时就已做好,而不是等到调用时。
[]也可以传引用,像[&length],如果length值在调用前发生变化,调用时就是取其当前值,和参数传值传址类似。
还有隐式传递(implicit),上面的[length]换成[=]表示编译器自己推断(infer)函数体内哪些变量需要传递进来,形式是传值,[&]则表示全部传址。
隐式显示传递结合使用:第一个必须是&或=,[&,length]表示length值传递,其余全是引用传递,[=,&length]表示length传引用,其余传值。
传引用一定要保证调用L时,引用的那些变量还在生存期。
L表达式也可以作为返回值,此时更要慎用引用了。
关于传值:默认情况下[]中的传值变量是只读的,不可改,需要改写的话加mutable关键字,此时参数列表不可省略
int h =4;
auto f2 = [h](){h++; return 42; };
关于L表达式的返回值,在没有返回类型说明的情况下,函数体内如果多于一个return语句,则会被认为是void无返回值。
typedef int(*func)(); void f4(func f) { cout<f4(f2)这里按照SBL所讲应该编不过,因为f2被推断为void类型,f4(f3)可以编过,但实际上编过了。 需要把f2改成
auto f2 = []()->int {//...}
如果f2[]加入main的局部变量h,auto f2 = [h]()->int {//...}
会导致编译不过,f4的作用域看不到main的局部变量h。