stl讀書筆記(2)- 模板特例化

本來這個不屬於stl中的一個內容,但是我是stl中看到了這個。所以特此說出來,我不知道stl中在拷貝數據的時候,爲什麼要區分POD(plain old data)。我個人覺得應該是都可以的。

神馬叫做模板特例化,舉個簡單的例子:

template<typename T0, typename T1>
 14 class CTest
 15 {
 16 public:
 17     void Print()
 18     {
 19         printf("Come in\n");
 20     }
 21 };
 22 
 23 template<typename T1>
 24 class CTest<T1,int>
 25 {
 26 public:
 27     void Print()
 28     {
 29         printf("Come in1\n");
 30     }
 31 };
上面進行了模板特例化,如果定義CTest<char *, int>,則選擇的特例化的模板CTest<T1, int>。


如圖是sgi_stl中使用了模板特例化,這樣統一iterator_category, value_type, difference_type, pointer,reference類型。(我個人觀點,我覺這個真的沒啥用,不知道爲什麼要這樣泛化性編程,難道支持不同的編譯器?)

sgi_stl特例化真正的用途是爲了區分POD類型,


__uninitialized_fill_aux實現調用如下:


如何區別調用上面不同的函數了?是通過__type_traits<_Tp>模板特例化來進行區別的,具體定義如下圖:



template <class _Tp>
struct __type_traits { 
   typedef __true_type     this_dummy_member_must_be_first;
                   /* Do not remove this member. It informs a compiler which
                      automatically specializes __type_traits that this
                      __type_traits template is special. It just makes sure that
                      things work if an implementation is using a template
                      called __type_traits for something unrelated. */

   /* The following restrictions should be observed for the sake of
      compilers which automatically produce type specific specializations 
      of this class:
          - You may reorder the members below if you wish
          - You may remove any of the members below if you wish
          - You must not rename members without making the corresponding
            name change in the compiler
          - Members you add will be treated like regular members unless
            you add the appropriate support in the compiler. */
 

   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;
};



// Provide some specializations.  This is harmless for compilers that
//  have built-in __types_traits support, and essential for compilers
//  that don't.

#ifndef __STL_NO_BOOL

__STL_TEMPLATE_NULL struct __type_traits<bool> {
   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;
};

#endif /* __STL_NO_BOOL */

__STL_TEMPLATE_NULL 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;
};

__STL_TEMPLATE_NULL 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;
};

__STL_TEMPLATE_NULL 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;
};

用來區分了POD類型,如果不屬於POD類型,不能夠直接調用memcpy函數,需要調用對象構造函數。(但是我覺得完全可以都調用構造函數,POD也可以認爲是個“”類型“”,不知道到stl爲啥要這麼實現)


綜上所述,我覺得stl中不要區別POD類型,有可能還有些細節東西沒有明白。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章