在完成了STL與泛型編程前三周的學習之后,有一些總結和心得在這里通過學習筆記的方式分享出來,筆記我是跟著老師在視頻中所講的內容按照順序記錄的,也不能說是流水賬,對課程中的一些問題還是添加了自己的理解和分析,供也在學習C++的小伙伴用作學習交流,如有理解不到位的地方,歡迎批評指正。
上兩周,老師就分配器和容器的結構與分類做了詳細的介紹,本周接著之前的內容繼續學習STL的另一個重要組成部分——算法。
一.算法簡介
從語言層面上講,STL幾個重要部件中,只有算法Algorithm是函數模板,容器Container、迭代器Iterator、仿函數Functor、適配器Adaptor、分配器Allocator都是類模板。
算法是看不見容器的,它無法直接獲得容器中的信息。它所需要的一切信息都必須從迭代器取得,所以迭代器必須能夠回答算法的所有提問才能搭配該算法的所有操作。
不同容器提供了不同的迭代器,各種迭代器之間實際是一種繼承關系:
可以隨意位置進出的容器迭代器繼承自雙向進出的容器迭代器,雙向進出的容器迭代器繼承自單向進出的容器迭代器,單向進出的容器迭代器又繼承自input_iterator,output_iterator非容器提供。
二.Iterator_category和type_traits對算法的影響
對于以上代碼,是計算兩個迭代器之間的距離,返回類型是difference_type;從上面的代碼可以看出,算法本身是一個主函數,根據迭代器不同的分類而調用不同的次函數。
至于type_traits對算法的影響,老師舉了一個copy算法的例子:
該算法需要三個變量,即來源端起始端、來源端終止端以及目的端起始端。從課件可以看出,算法copy不斷地檢查,到了分支的地方,決定調用哪個次函數,來保證算法的最高效。
算法源碼中對iterator_category沒有限制,但會有“暗示”:
在C++標準庫中,它提供的algorithms以函數形式呈現,老師舉了7個算法當作例子。
1.算法accumulate
2.算法for_each
3.算法replace,replace_if,replace_copy
4.算法count,count_if
5.算法sort(這里需要注意:對于unordered容器,不需要調用sort算法,遍歷之后元素自動排序,自然形成sorted狀態)
6.算法find,find_if(這里需要注意的是:對于unordered容器,有自己的find算法,對于array,vector,list,forward_list,deque容器,它們帶有成員函數sort,因此標準庫中的find算法不適用)
7.算法binary_search(這里需要注意的是:lower_bound(v.begin(),v.end(),x),元素x安插在能夠安插進去的最低點;upper_bound(v.begin,v.end(),x),元素x安插在能夠安插進去的最高點)
三.仿函數(functors)
當要求算法需要有一些特定準則時,就會編寫仿函數去告訴算法。標準庫提供的functors有幾大類:算術類(Arithmetic)、邏輯運算類(Logical)、相對關系類(Relational),且標準庫提供的functors都有繼承關系。
仿函數functors的可適配(adaptable)條件:希望functors可以被修改,則必須選擇繼承適當的函數struct;adaptor提問,functors回答,才能融合進STL中。
存在多種Adapters:Functor Adapter與Functor、Iterator Adapter與Iterator、Container Adapter與Container之間都是內含的關系,其實就相當于改造。
在之前的內容中,我們學過容器stack和容器queue可以用Sequence當作底層容器,此時stack和queue被稱作容器適配器。同樣也存在函數適配器,這里老師舉了函數適配器binder2nd和not1的例子:
Binder2nd繼承自unary_function,將某個Adaptable?Binary function轉換為Unary Function:
這里需要注意的是:Typename()表示創建臨時對象,在很長的提問之前都加上typename
C++11之后又添加了新型適配器bind,std::bind可以綁定functions、function?objects、member functions以及data members
四.迭代器適配器Iteratoradaptors
1.reverse_iterator
reverse_iterator默認排序是由小到大,用rbegin()和rend()來由大到小排序。
逆向迭代器取值,是將對應正向迭代器退一位:
2.inserter
上述代碼中foo是容器,it是迭代器
這個adapter將iterator的賦值操作改為安插(insert)操作,并將iterator右移一個位置。如此便可連續執行表面上賦值而實際上insert的行為。
另外,在C++標準庫中,除了迭代器適配器,還有X適配器ostream_iterator和instream_iterator