ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
仿函数就是函数对象,只不过仿函数是老的叫法。仿函数和函数指针都可以作为参数传入函数,但仿函数的优势在于,它对类型抽象度高,并且能够和函数适配器进行匹配,但函数指针却不行。 类似于迭代器需要包含五种相应类型,为了满足可配接能力,仿函数需要定义一些类型,这在分析适配器代码的时候会看到。这个任务交给了一个基类来完成,它的内部定义了这些类型,其它的仿函数只需要继承这些基类即可。基类定义如下: ~~~ template <class Arg, class Result> struct unary_function { // 一元仿函数 typedef Arg argument_type; // 函数/仿函数唯一参数类型 typedef Result result_type; // 函数/仿函数返回值 }; template <class Arg1, class Arg2, class Result> struct binary_function { // 二元仿函数 typedef Arg1 first_argument_type; // 仿函数参数1 typedef Arg2 second_argument_type; // 仿函数函数2 typedef Result result_type; // 仿函数返回类型 }; ~~~ 用户自定义的仿函数,只要继承了相应的基类,就具有了可配接能力。以下是测试代码: ~~~ #include <iostream> #include <vector> #include <algorithm> using namespace std; template <class T> class les: public binary_function<T, T, T> { public: bool operator() (const T &lhs, const T &rhs) const { return lhs < rhs; } }; int main() { int array[] = {3,4,1,7,5,9,5}; vector<int> vec(array, array+7); // 找出容器内小于10的元素个数 cout << count_if(vec.begin(), vec.end(), bind2nd(les<int>(), 7)); return 0; } ~~~ 运行结果: ![](https://box.kancloud.cn/2016-08-11_57ac4c8b6c213.jpg) 注意上面的les仿函数继承自二元仿函数binary_function,这样它就能与适配器bind2nd正常配接,否则会在运行期发生错误。 按操作数个数划分,可分为: - 一元仿函数 - 二元仿函数 按功能划分,可分为: - 算术运算 - 关系运算 - 逻辑运算 以plus仿函数为例: ~~~ template <class T> struct plus : public binary_function<T, T, T> { T operator()(const T& x, const T& y) const { return x + y; } }; ~~~ 其它的仿函数几乎都是这个模样,有些细节上略有不同,这是根据操作符本身的性质决定的。 参考: 《STL源码剖析》 第七章。