定制操作——为算法定义额外的版本,允许我们提供自己定义的操作来代替默认运算符。
1、向算法传递函数
谓词:一个可调用的表达式,其返回结果是一个能用作条件的值。
标准库算法使用的谓词分为两类:一元谓词(只接受单一参数)和二元谓词(接受两个参数)。接受谓词参数的算法对输入序列中的元素调用谓词。
stable_sort(),稳定排序算法维持相等元素的原有顺序。
2、lambda表达式
希望进行的操作需要更多的参数。
可以向一个算法传递任何类别的可调用对象(如函数和函数指针),还有两种可调用对象:重载了函数调用运算符的类和lambda表达式。
lambda表达式的形式:
[capture list](parameter list) -> return type{ function body}
lambda必须使用尾置返回。
如果lambda的函数体包含任何单一return 语句之外的内容,且未指定返回类型,则返回void。
一个lambda只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数体中使用该变量。
捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和它所在函数之外声明的名字。
当定义一个lambda时,编译器生成一个与lambda对应的新的类类型。当向一个函数传递一个lambda时,同时定义了一个新类型和该类型的一个对象:传递的参数就是此编译器生成的类类型的未命名对象。
默认情况下,从lambda生成的类都包含了一个对应该lambda所捕获的变量的数据成员,lambda的数据成员呢也在lambda对象创建时被初始化。
变量的捕获方式有两种:值捕获和引用捕获
值捕获:前提是变量可以拷贝,被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝。
引用捕获:必须确保被引用的对象在lambda执行时是存在的。
不能拷贝ostream对象,只能捕获其引用。
尽量保持lambda的变量捕获简单化,尽量减少捕获的数据量,避免潜在的捕获导致的问题,如果可能的话逼民捕获指针或引用。
隐式捕获
&告诉编译器采用捕获引用方式,=表示采用值捕获方式。
可变lambda
对于一个值被拷贝的变量,lambda不会改变其值。如果希望改变一个被捕获的变量的值,必须在参数列表首加上关键字mutable。
参数绑定:
如果一个操作需要很多语句才能完成,通常使用函数更好。如果lambda的捕获列表为空,通常可以用函数来代替它。
标准库bind函数,定义在functional中,可以将bind函数看做一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。一般形式如下
auto newCallable = bind(callable, arg_list);
arg_list是一个逗号分隔的参数列表,对应给定的callable的参数。即,当我们调用newCallable时,newCallable会调用callable,并传递给它arg_liist中的参数。
浙公网安备 33010602011771号