本來這個不屬於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類型,有可能還有些細節東西沒有明白。