基本概念
①.调用运算符
即:() 。跟随在函数名之后的一对括号 “()”,起到调用函数的效果,传递给函数的实参放置在括号内。
②.谓词
是一个可调用表达式,其返回结果是一个能用作条件的值。根据可接收的参数分为一元谓词和二元谓词;接收谓词参数的算法对输入序列中的每个元素调用谓词。
③.可调用对象
对于一个对象或者一个表达式,如果可以对其使用调用运算符,则称为可调用对象。
④.调用形式
一种调用形式对应了一个函数类型,指明了调用返回类型以及传递的参数类型,比如:int (int,int) 。
函数对象
-
定义
①.概念
如果类定义了调用运算符,则该类的对象称作函数对象,即这些对象的行为像函数一样。
②.定义
函数对象除了 operator() 之外也可以包含其他成员。class PrintString { public: PrintString(ostream &o = cout,char c = ''):os(o),sep(c) {} void operator()(const string &s) const//重载函数调用运算符 { os << s << sep; } private: ostream &os; char sep; } PrintString printer; printer("hello world");//类似函数调用
-
标准库中可调用对象
①.标准库函数对象
标准库在头文件 functional 中定义了一系列模版类,每个类都分别定义了一个执行命名操作的调用运算符,如:less 、greater 等。
②.使用
表示运算符的函数对象常用来替换算法中的默认运算符,比如排序算法默认使用 operator< 将序列按升序排列,我们可以传入一个 greater 对象,使按降序排列。vector<string> vec {"111","2222","33"}; sort<vec.begin(),vec.end(),greater<string>()>;
-
可调用对象与function
①.不同类型可具有相同调用形式
//普通函数 int add(int i,int j) { return i+ j } //函数指针 int (*addptr)(int i,int j) = add; //lanbda 表达式 auto mod = [](int i,int j) {return i%j } //函数对象类 class divide { int operator()(int i,int j) { return i/j; } } //以上各种类型的可调用对象都具有相同的调用形式 int(int,int)
②.标准库 function 类型
function 定义在头文件 functional 中,是一个模版类型,可以用来存储可调用对象。//普通函数 int add(int i,int j) { return i+ j } //函数指针 int (*addptr)(int i,int j) = add; //lanbda 表达式 auto mod = [](int i,int j) {return i%j } //函数对象类 class divide { int operator()(int i,int j) { return i/j; } } function<int(int,int)> f1 = add; function<int(int,int)> f2 = divide();//函数对象类 function<int(int,int)> f3 = [](int i,int j) {return i%j }; function<int(int,int)> f4 = addptr;//函数指针
bind 函数
-
定义
①.概念
可将 bind 函数看作是一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来适应源对象的参数列表。
调用 bind 的一般形式:auto newCallable = bind(callable,arg_list);当我们调用 newCallable 时,newCallable 会调用 callable ,并传给它 arg_list 中的参数。
②.占位符
arg_list 中的参数可能包含形如 _n 的名字,这些参数是“占位符”,表示 newCallable 的参数。数值 n表示生成的可调用对象中参数的位置:_1 为 newCallable的第一个参数,_2 为第二个参数,以此类推。
③.头文件
标准库函数 bind 定义在头文件 functional 中,并且使用时需要 using namespace std::placeholders。 -
应用
①.参数绑定
通过参数绑定可以更改可调用对象的实际需要外部传递的参数数量。
②.重排参数顺序
通过 bind 可以重排传递的参数顺序。
③.绑定引用参数
bind 中绑定引用参数需要使用标准库函数 ref ,不能使用 &。
ostream &os = cout;
ostream &print(ostream &os,const string &s,char c)
{
return os << s << c;
}
// 上述函数中 ostream 对象必须传递引用,用 bind 绑定如下
auto p = bind(print,ref(os),_1,c);