《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