一、定制操作
- 1、predicate谓词(返回可以作为条件的类型的操作)
谓词是一个可调用的表达式,其结果是一个能作为条件的值,谓词分为unary predicate 和 binary predicate - 2、callable object可调用对象
函数及函数指针
重载函数调用运算符的类
lambda表达式 - 3、向泛型算法中传递局部变量
(1)lambda表达式:针对于只在一两个地方使用的简单操作;
(2)bind函数:在很多相同的地方使用相同的操作,或者操作需要很多语句才能完成。
(3)重载函数调用运算符的类,lambda表达式就是这种函数对象的简化形式。
二、lambda表达式概述:
1、[capture list] (parameter list) -> return type {lambda body }
- lambda表达式可以理解为一个未命名的内联函数,与函数不同的是:
(1)lambda可以定义在函数的内部;
(2)capture list 是一个lambda所在函数中定义的局部变量的列表(通常为空);
(3)lambda必须使用尾置返回类型来指定放回类型,且:如果一个lambda的函数体中包含任何单一return语句之外的内容,且未指定返回类型,则返回void。
2、使用capture list
-
一个lambda只有在其capture list中捕获一个所在函数的局部变量,才能在函数体中使用这个变量。
-
捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和他所在函数之外声明的名字
3、lambda的捕获和返回
- 当定义一个lambda时,编译器生成一个与lambda相对应的(未命名)的类类型;当向一个函数传递一个lambda时,同时定义类一个新类型和该类型的一个对象:传递的参数就是此编译器生成的类类型的未命名的对象。
- 类似的,当使用auto定义一个使用lambda初始化的变量时,定义了一个从lambda生成的类型对象。此时capture list中的内容已经传递完成,可以通过引用捕获或者是mutable修饰可以改变被捕获的变量值。当以引用方式捕获一个变量时,必须保证再lambda执行时变量是存在的。
- lambda捕获列表: 空的列表;显式捕捉列表;隐式捕捉列表:应注意只能隐式一种捕捉列表,要么引用捕获缺省,要么值捕获缺省。隐式捕获只是提供了一种简化的方式;最好使用显式的方式
三、参数绑定(标准库bind函数)
bind相关的内容都包含在头文件 #include<functional>中
1、bind可以看做一个通用的函数适配器,调用bind的一般形式为:auto newCallable = bind( callable, arg_list);
-
newCallable本身是一个可调用对象,它通过调用callable来完成操作;
-
arg_list是callable的参数列表,其中_n是newCallable的参数,其他的为直接传递来的参数。
-
arg_list中通过形如_n的“占位符”来表示newCallable的参数,它们占据着传递给newCallable的参数;
-
_n中的n为newCallable中参数的位置,如_1为第一个参数,这样的写法可以重排参数的顺序。
2、名字_n都是定义在名为placeholders的命名空间中,而这个命名空间本事定义在std中。
3、bind引用参数
- bind引用参数不能通过&符号来实现,要通过专门函数来实现:
ref(arg); // 返回一个对象,包含给定的引用类,此对象是可以拷贝的。
cref(arg); //生成一个const引用的类。
4、bind的使用流程:
- 定义一个callable,它的形参列表为parameter;
- 定义auto newCallable = bind( callable, arg_list);其中arg_list与parameter对应,而其中不是占位符的直接传递了局部变量,而占位符是newCallable的参数,调用generic_algorithm中的参数。