🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
《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.