本周課程主要內容為標準庫中STL之外的一些內容,包括一個萬用的Hash Function、tuple、type traits、cout和moveable。
1、一個萬用的Hash Function
這個萬用的Hash Function有3種型式,如圖1.1和圖1.2,其中型式3是G4.9版本才有的新型式。



本節(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之后引進的一種存放各種不同類型元素的集合。


本節(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的特化版本。







本節(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支持。


本節(jié)內容總結如下:
(1)cout是一個iostream類的對象,它有一個成員運算符函數(shù)operator<<,每次調用的時候就會向輸出設備輸出內容;
(2)從根本上說,cout是函數(shù)調用,不過這函數(shù)有些特殊,用的是運算符重載,確切地說是重載了“<<”運算符。
5、moveable
本節(jié)主要講述moveable元素對于容器速度效能的影響,其中在vector中差別較大,在list、deque、multiset、unordered_multiset中差別不大。





本節(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