視頻筆記 CppCon 2015:Marshall Clow “Type Traits - what are they and why should I use them?"
阿新 • • 發佈:2017-05-16
for -- per 是的 point 分類 ace ner null Video: CppCon 2015:Marshall Clow “Type Traits - what are they and why should I use them?"
https://www.youtube.com/watch?v=VvbTP_k_Df4
如果你需要寫關於不同類型的代碼,而不是具體的類型,你可能需要了解Type Traits
4:47 C++多少種類型?14
; // false
std::rank的用法,輸出int
std::cout << std::rank<float>::value << ‘\n‘; // 0
std::cout << std::rank<int[1][1]>::value << ‘\n‘; // 2
std::cout << std::rank<int[2][3][4]>::value << ‘\n‘; // 3
有些可以輸出type
std::remove_const<const int>::type --> int
std::remove_const<int>::type--> int
BTW:
- void, nullptr: 只有一個成員在這個type裏面
- struct 實際上和class 是一樣的,只是default access是public
- array vs pointer: array有一片物理區域,pointer僅僅是個地址。pointer可以為空
08:21 type trait的定義
就是一個結構,裏面包含模板的類型信息 例如,下面是個簡單用法,輸出true/false #include <iostream> #include <type_traits> std::cout << std::is_floating_point<float>::value << ‘\n‘; // true std::cout << std::is_floating_point<int>::value << ‘\n‘
- std::is_permulation 比較兩個序列是否相同,順序可以不同
- std::enable_if & SAFINAE
每個人都覺得自己實現的vector會比stl的好。但事實上,STL裏面的實現包含許多corner cases,非常復雜。 strong exception guarantee: 要麽完全成功,要麽出錯拋異常,並且需要完全恢復的操作前的狀態。例如,如果vector內存reserve不夠,需要申請新的內存,並且把已經有的對象拷貝進入新內存。如果拷貝到一半出錯,需要完全恢復這些操作,讓vector恢復到之前的狀態,並且拋出異常。
拷貝的代價很高(需要創建,構造,析構舊對象)。如果T支持move,可以利用move提高效率。但是如果move構造函數會拋出異常,既無法繼續,又無法恢復!所以,必須要求no throw move-constructible! no throw意味著move永遠都能成功。並不是所有的T都能實現no throw的,需要特別留意。
如果vector裏面是int,或者T是個結構只包含基本類型。只要申請新內存,拷貝內存(never throw),釋放舊內存,效率可言很高。有一種type trait叫做trivially copyable描述這種情況。
這些都不是必要的,沒有這些也能正確實現。但是有了這些,可以優化得很好。
43:06 Questions- 44:00 可以生成自己的type trait嗎?可以。例如,std::is_floating_point,如果自己實現該怎麽實現。針對float, double, long double這幾種類型特化,返回true,默認返回false。有方法甚至可以實現這樣的type trait: 一個結構是否包含一個member function叫做foo,並且參數是什麽什麽,返回什麽。
- 47:05 對 SFINAE 的例子,一般有兩種實現,一種是使用enable_if,另一種...。enable_if 有什麽優勢?這種方法更簡單清晰,不容易出錯。具體見視頻。
- 50:16 是的,將來 concept 的引入會很大程度的改變現在的實現
視頻筆記 CppCon 2015:Marshall Clow “Type Traits - what are they and why should I use them?"