《C++ primer》中只说了适用于函数对象的适配器,其实还有针对函数和成员函数的适配器。这些适配器使我们能够将函数/成员函数当作仿函数使用,例如搭配各种泛型算法。从本质上说,是因为让这些函数变成为“可配接的”,即一元仿函数必须继承自unary_function,二元仿函数必须继承自binary_function。
一般函数必须以ptr_fun处理:
一般函数当作仿函数传给STL算法,就语言层面是可以的,但它仍然是不可配接的,因为它还没有具备标准库中仿函数(例如plus)的性质。所以,它无法运用于其它的适配器(例如not1)。
成员函数必须以mem_fun处理:
当容器的元素类型是引用或指针,而我们又以虚成员函数作为仿函数,便可以通过泛型算法完成所谓的多态调用。这是泛型与多态之间的一个重要接轨(稍后解释)。
例如:
~~~
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Shape {
public: virtual void display() = 0;
};
class Rect : public Shape {
public: virtual void display() { cout << "Rect "; }
};
class Circle : public Shape {
public: virtual void display() { cout << "Circle "; }
};
class Square : public Rect {
public: virtual void display() { cout << "Square "; }
};
int main()
{
vector<Shape*> v;
v.push_back(new Rect);
v.push_back(new Circle);
v.push_back(new Square);
v.push_back(new Circle);
v.push_back(new Rect);
for (int i = 0; i < v.size(); i++)
(v[i])->display();
cout << endl;
for_each(v.begin(), v.end(), mem_fun(&Shape::display));
cout << endl;
return 0;
}
~~~
关于上述代码的语法,参见文章“类成员函数指针”。
代码红色部分把成员函数转换成了可配接的仿函数,通过这句话就可以解释“这是泛型与多态之间的一个重要接轨”的含义了。
泛型:for_each能够接纳各种类型的函数。
多态:根据容器实际对象进行多态调用。
参考:
《STL源码剖析》 P430、P454.
- 前言
- 顺序容器 — heap
- 关联容器 — 红黑树
- 关联容器 — set
- 关联容器 — map
- 关联容器 — hashtable
- 关联容器 — hash_set
- 关联容器 — hash_map
- 算法 — copy
- 顺序容器 — stack
- 顺序容器 — queue
- 顺序容器 — priority_queue
- 顺序容器 — slist
- construct()和destroy()
- 空间配置器
- 函数适配器
- 迭代器以及“特性萃取机”iterator_traits
- 算法 — partial_sort
- 算法 — sort
- 仿函数
- 适配器(adapters)
- C++简易vector
- C++简易list
- STL算法实现
- C++模板Queue