Boolan_STL與泛型編程_第五周筆記

本周課程主要內容為標準庫中STL之外的一些內容,包括一個萬用的Hash Function、tuple、type traits、cout和moveable。

1、一個萬用的Hash Function

這個萬用的Hash Function有3種型式,如圖1.1和圖1.2,其中型式3是G4.9版本才有的新型式。

圖1.1
圖1.2
圖1.3

本節(jié)內容總結如下:

(1)hash function設計原則:產生的hash code盡可能減少沖突, 使元素能夠盡可能多的落在不同的籃子里;

(2)圖1.3中,在①中加入了seed(最終被視為hash code),從而使得模板變成1+n的形式,通過遞歸調用②中的hash_val函數(shù),不斷調用④中的hash_combine函數(shù)來改變seed,同時減少接收的參數(shù),最終遞歸結束時變成1+1的形式,調用③中的hash_val函數(shù),也會調用④中的hash_combine函數(shù),最終確認seed值,也就是算出最后的hash code;

(3)計算hash code時,0x9e3779b9是借用的黃金比例。

2、tuple

tuple是指元之組合,數(shù)之組合,它是C++2.0之后引進的一種存放各種不同類型元素的集合。

圖2.1
圖2.2

本節(jié)內容總結如下:

(1)創(chuàng)建一個四個元素的tuple t:

tuple<string,int,int,couple<double>>??t;//要標明每個元素的類型;

創(chuàng)建一個tuple,并賦初值:

tuple<int, float, string> t1(41, 6.3, "nice");

(2)get<0>(t1)取t1的第0個元素,get<1>(t1)取t1的第1個元素,以此類推;

(3)make_tuple 輔助函數(shù)直接放值,即創(chuàng)建一個tuple,并寫入元素:

auto t2 = make_tuple(22, 44, "stacy");?

(4)tuple的用法:

tie綁定,將tuple中對應的各個元素綁定到tie中,tuple_size獲取tuple中value個數(shù),tuple_element獲取tuple中第幾個元素的類型;

(5)tuple會自動遞歸,把元素分隔為head和tail, tail會再分隔為head和tail,直到tail只有一個元素為止,層層繼承, tail作為基類,head作為數(shù)據(jù)成員;

(6)tuple是通過繼承的方法來不斷地剔除第一個參數(shù),最終來實現(xiàn)對每一個元素的操作,而Hash Function是不斷調用。

3、type traits

type traits用于回答class中的默認構造、拷貝構造、拷貝賦值、析構函數(shù)重要不重要,是否是POD等,為算法服務。

對于自定義的類型,可以自己定義type traits的特化版本。

圖3.1
圖3.2
圖3.3
圖3.4
圖3.5
圖3.6
圖3.7

本節(jié)內容總結如下:

(1)string的析構函數(shù)不是虛函數(shù),在設計上是不打算讓用戶繼承的,所以詢問是否有虛函數(shù)時是0.,是否有多態(tài)時是0;

(2)Zoo(const Zoo&) = delete; 不要編譯器默認的。

Zoo(Zoo&&) = default; 要編譯器默認的搬離構造函數(shù), 用戶不寫時與其意義相同。

Zoo& operator=(const Zoo&) = default; 默認,用戶不寫時與其意義相同。

Zoo& operator=(const Zoo&&) = delete; 不要編譯器默認的搬離賦值函數(shù)。

(3)對于is_void類模板,繼承自_is_void_helper類模板,先把const、volatile屬性拿掉,再傳給__is_void_helper,利用它的泛化和特化void,判斷是否是void;

(4)對于is_integral類模板,也是先把const、volatile屬性拿掉,再利用__is_integral_helper的泛化和偏特化判斷,如果不是和某種特化版本匹配的類型,那么就會使用泛化版本,泛化版本的回答是false;

(5)有些type traits的實現(xiàn)在標準庫中找不到源代碼,例如is_class、is_union、is_enmum、is_pod等,這種是由編譯器實現(xiàn)的。

4、cout

cout是C++編程語言互換流中的標準輸出流,需要iostream支持。

圖4.1
圖4.2

本節(jié)內容總結如下:

(1)cout是一個iostream類的對象,它有一個成員運算符函數(shù)operator<<,每次調用的時候就會向輸出設備輸出內容;

(2)從根本上說,cout是函數(shù)調用,不過這函數(shù)有些特殊,用的是運算符重載,確切地說是重載了“<<”運算符。

5、moveable

本節(jié)主要講述moveable元素對于容器速度效能的影響,其中在vector中差別較大,在list、deque、multiset、unordered_multiset中差別不大。

圖5.1
圖5.2
圖5.3
圖5.4
圖5.5

本節(jié)內容總結如下:

(1)在vector中拷貝300萬個元素,調用MCtor或者CCtor的次數(shù)遠大于300萬次的原因是,容器vector是呈二倍成長的,每次增加容量均會調用MCtor或者CCtor;

(2)使用move雖無法減少拷貝的次數(shù),但是可以提高拷貝構造的效率;

(3)move assignment、move constructor是淺拷貝;

(4)string具有moveable功能。

6、課后補充學習

traits的本質定義:加上一層間接性,換來以定的靈活性。

具體地說就是通過定義一些結構體或類,并利用模板類特化和偏特化的能力,給類型賦予一些特性,這些特性根據(jù)類型的 不同而異。traits在STL中為了提供通用的操作而又不損失效率在程序設計中可以使用這些traits來判斷一個類型的一些特性,引發(fā)C++的函數(shù)重載機制,實現(xiàn)同一種操作因類型不同而異的效果。有人說 traits的編程技巧極度彌補了C++語言的不足 。

template <typename T>

structis_void

{staticconstboolvalue?=false;?};

template?<>

structis_void

{staticconstboolvalue?=true;?};

Is_void<false>::value調用第一份代碼,也就是說只要我們傳入一個參數(shù)像這樣:Is_void<T>::value,其中T可以為任意類型,我們就可以判斷這個類型是不是void在編譯期。

更詳細的學習內容見:http://www.cnblogs.com/youthlion/archive/2011/12/01/2255618.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容