泛型編程拾遺

  首先請你們思考一個問題:如下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思想》

相關文章
相關標籤/搜索