C/Cpp / STL / 类型萃取
作用
類型萃取使用模板技術來萃取類型(包含自定義類型和內置類型)的某些特性,用以判斷該類型是否含有某些特性,從而在泛型算法中來對該類型進行特殊的處理用來達到提高效率或者其他的目的。
類型萃取的實現的基石是模板的偏特化和全特化,詳解鏈接:https://blog.csdn.net/itworld123/article/details/104718336?。
實例說明
這里采用的實例是 STL 的 destroy() 函數的實現,原型如下圖所示:(stl_contruct.h)
該函數的作用是析構?[ first , last ) 范圍內的對象。
這里面就有個問題,ForwardIterator 是否是類對象,如果是的話就可以執行其析構函數,否則是不進行任何處理的?,F在的關鍵就是怎么才知道?ForwardIterator?的數據類型是屬于哪一類呢?
為了解決上述問題,這里面就需要使用類型萃取技術了。
首先我們通過 value_type(first) 獲取到了模板的數據類型。進入 __destroy() 函數,如下所示:(stl_contruct.h)
好的,關鍵時刻來了!trivial_destructor 就決定了類型 T 是否含有析構函數!它是如何被聲明的呢?這里需要看下?__type_traits<T> 的代碼,如下所示:(type_traits.h)
struct __true_type { };struct __false_type { };template <class type> struct __type_traits {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; };__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; };__STL_TEMPLATE_NULL 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; };__STL_TEMPLATE_NULL 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; };__STL_TEMPLATE_NULL 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; };__STL_TEMPLATE_NULL 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; };__STL_TEMPLATE_NULL 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; };__STL_TEMPLATE_NULL 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; };__STL_TEMPLATE_NULL 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; };__STL_TEMPLATE_NULL 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; };__STL_TEMPLATE_NULL 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; };上述代碼中充斥著?__type_traits 的原生版本、偏特化版本以及全特化版本,也就是說,STL采用窮舉的方案,解決了如何判斷各種數據類型是否有析構函數的問題。
若?has_trivial_destructor =?__true_type,則類型 T 不是類類型,所以不需要進行析構,執行代碼如下:(stl_contruct.h)
若?has_trivial_destructor =?__false_type,則類型 T 是類類型,所以需要進行析構,執行代碼如下:(stl_contruct.h)
這樣就完成了 destroy() 函數的功能。
?
參考:https://blog.csdn.net/dawn_sf/article/details/70038126
(SAW:Game Over!)
總結
以上是生活随笔為你收集整理的C/Cpp / STL / 类型萃取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/Cpp / STL / vector
- 下一篇: OS / Linux / epoll 各