- traits編程 彌補了C++本身的不足
- STL只對迭代器進行規范制定出了iterator_traits,SGI在此基礎上進一步擴展,產生了__type_traits
- 雙下劃線的含義是這個是SGI內部使用的東西,不屬于STL標準
- iterator_traits 負責萃取迭代器的特性
- __type_traits負責萃取型別特性。比如是否具備non-trivial default ctor??non-trivial copy ctor?non-trivial assignment operator?non-trivial dtor? 如果答案是否定的,就可以對這個型別進行構造、析構、拷貝、賦值等操作時,采取最有效率的措施.
- 比如 根本不調用身居高位的constructor、destructor,直接進行內存層面上的操作,比如malloc()、memcpy()等等,進一步提高效率
- __type_traits 允許針對不同的型別屬性在編譯時期完成函數的派送指定。這對于撰寫模板很有幫助,比如對一個元素型別未知的數組進行copy操作的時候,如果事先知道元素的型別是否有一個trivial copy constructor,就可以幫助函數確定是否可以使用memcpy() 或者 memmove()
- 根據iterator_traits的經驗,程序應該采用如下的方式使用__type_traits? 其中T代表任意的型別
__type_traits<T>::has_trivial_default_constructor
__type_traits<T>::has_trivial_copy_constructor
__type_traits<T>::has_trivial_assignment_operator
__type_traits<T>::has_trivial_destructor
__type_traits<T>::is_POD_type
- 上述的公式 響應真或者假,從而函數決定采用什么樣的處理策略。但是不僅僅是一個bool數值,而應該是一個具備真假性質的對象。因為需要利用它的響應結果來進行參數的推導,而編譯器只會對具備class object形式的參數才會進行類型的推導
- 因此,上述公式應該返回的是 如下的形式,這兩個空白的classes沒有任何的成員,不會帶來額外的負擔,但是能表明真假,滿足需求
struct __true_type{};
struct __false_type{};
- 為了滿足上述的式子,__type_traits必須定義一些typedef ,其類型不是__true_type,就是__false_type
- 下面是SGI的做法
struct __true_type{};
struct __false_type{};template <class type>
struct __type_traits{/** 不要移除這個成員,他通知"有能力自動將__type_traits特化"的編譯器說,現在的* 這個__type_traits是特殊的,確保萬一編譯器也使用一個__type_traits而其實* 與此處定義并沒有任何關聯的模板的時候,不出現錯誤*/typedef __true_type this_dummy_member_must_be_first;/** 遵守以下的約定,因為編譯器有可能自動為各個型別產生專屬的__type_traits* 特化版本* 1,可以重新排列以下成員的次序* 2,不可以刪除以下成員* 3,絕對不可以將以下成員重新命名,但是沒有改變編譯器中對應的名稱* 4,新加入的成員視為一般成員,除非你在編譯器中加上適當的支持*/typedef __false_type has_trivial_default_constructor;typedef __false_type has_trivial_copy_constructor;typedef __false_type has_trivial_assignment_operator;typedef __false_type has_trivial_destructor;typedef __false_type is_POD_type;
};
- 將所有的內嵌型別都定義為__false_type,默認是最為保守的數值。
- 隨后可以根據每一個標量類型設計適當的__type_traits的特化版本
特化版本
- 以下針對C++基本型別char \ signed char \ unsigned char \ short \ unsigned short \ int? \ unsigned int \ long? \ unsigned long \ float \ double \ long double 提供了特化版本,每一個的成員數值都是true_type,即這些型別都可以采用最快速的方式(例如 memcpy) 進行拷貝 或者 賦值操作
- SGI STL<stl_config.h> 將以下出現的__STL_TEMPLATE_NULL d定義為template<> ,是所謂的class template explicit specialization
template<>
struct __type_traits<char>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<signed char>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<unsigned char>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<short>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<unsigned short>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<int>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<unsigned int>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<long>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<unsigned long>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<float>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<double>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<>
struct __type_traits<long double>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};template<class T>
struct __type_traits<T*>{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};
- 以上內容均將__STL_TEMPLATE_NULL 替換為 template <>?

- type_traits在SGI STL中使用很廣泛 例如:uninitialized_fill_n()全局函數、destroy()函數、copy()函數 (STL源碼剖析110頁),他們的思想都是一樣的,分為泛型和偏特化兩種模式,進行切換
- 一個class什么時候應該有自己的?non-trivial default ctor??non-trivial copy ctor?non-trivial assignment operator?non-trivial dtor?簡單的判斷準則是,如果這個類內含指針成員,并且對它進行內存動態配置,那么這個類就需要自己實現 non trivial XXX,即上述內容