首先請你們思考一個問題:如下6個問題能否共享一段代碼?html
答案是確定的。採用泛型編程對問題進行抽象,抽取出以上問題的共性即算法(algorithm)、容器(container)和迭代器(itera),這也是STL(Standard Template Library, 標準模板庫)的三要素。ios
1 template <class Iterator, class Act, class Test>
2
3 void process(Iterator begin, Iterator end, Act act, Test test) 4
5 //對容器中在給定範圍內(即起於begin止於end)全部知足給定條件的元素進行處理
6
7 { 8
9 for (; begin != end; ++begin) //從頭到尾遍歷容器內的元素
10
11 if (test(*begin)) act(*begin); //若當前元素知足條件,則對其採起行動
12
13 }
其中,算法是一系列切實有效的步驟(Act/Test);容器是數據的集合,能夠理解爲抽象的數組(6個問題中須要遍歷的數據集合);迭代器是算法與容器之間的接口,可理解爲抽象的指針或遊標(迭代器用以訪問容器內元素,C++中指針就是一種迭代器)。以上程序中看不到元素的數據類型T,甚至也看不到存放數據的容器container,這是由於元素已經被容器封裝,而容器經過迭代器參與算法。git
這麼說可能你們不是很理解,下面以第6個問題爲例,展現泛型編程的魅力:算法
1 //Generic Programming 範型編程 by acelit http://www.cnblogs.com/always-chang/
2 #include <iostream>
3 #include <iterator>
4 using namespace std; 5
6 template <class Iterator, class Act, class Test>
7 void process(Iterator begin, Iterator end, Act act, Test test) 8 //對容器中在給定範圍內(即起於begin止於end)全部知足給定條件的元素進行處理
9 { 10 for (; begin != end; ++begin) //從頭到尾遍歷容器內的元素
11 if (test(*begin)) act(*begin); //若當前元素知足條件,則對其採起行動
12 } 13 //判斷是否爲非數字字符
14 bool notDigit(char c) 15 { 16 return (c < '0') || (c > '9'); 17 } 18 //打印非數字字符
19 void printNondigit(char c) 20 { 21 cout << c << "不是數字字符" << endl; 22 } 23
24 int main() 25 { 26 process(istream_iterator<char>(cin), istream_iterator<char>(), printNondigit, notDigit); 27
28 return 0; 29 }
問題6中的標準輸入也是容器的一種,容器內元素類型爲char,template <class Iterator, class Act, class Test>經過模板泛化了容器(還有數組、列表、集合、映射、隊列、棧、字符串等),也泛化了元素(能夠是任何數據類型),甚至泛化了處理方法和限定條件(迭代器自己就是一種檢查容器內元素並遍歷元素的數據類型,這種數據類型包含一組肯定的操做來遍歷、訪問容器內的元素,固然遍歷方法有不少種了,好比從前日後、從後往前、隨機移動…)。編程
【泛化這個詞能夠理解爲‘隱藏’,這裏模板內僅有迭代器的聲明,可是迭代器的類型是經過容器來定義的。】數組
istream_iterator<char>表示元素爲char類型的標準輸入流(容器)迭代器,()內有標準輸入流對象cin表示容器開始位置,爲空表示容器結束位置。編碼
怎麼樣?泛型編程是否是使代碼異常簡潔,固然付出的代價是理解起來比較抽象了,這裏徹底看不到I/O讀取的過程,也看不到一般的迭代循環,使咱們徹底擺脫了底層編碼的細節,在更高、更抽象的層次上進行編程。spa
抽象和泛化使代碼簡潔高效、可重用性大大提升,是泛型編程的「屠龍之技」,也是咱們必須掌握的編程技能。指針
歡迎討論交流O(∩_∩)Ocode
istream_iterator詳見:
http://www.cplusplus.com/reference/iterator/istream_iterator/
更多迭代器和容器參考:
http://www.360doc.com/content/12/1128/13/9290626_250737796.shtml
本文參考:《冒號課堂——編程範式與OOP思想》