stl源码 vector不正规解析2 (自用)VS2019
緊接上一篇,我們接著看vector中的其他別名,也就是類型定義,先把接下來的代碼貼上來:
using value_type = _Ty;using allocator_type = _Alloc;using pointer = typename _Alty_traits::pointer;using const_pointer = typename _Alty_traits::const_pointer;using reference = _Ty&;using const_reference = const _Ty&;using size_type = typename _Alty_traits::size_type;using difference_type = typename _Alty_traits::difference_type;private:using _Scary_val = _Vector_val<conditional_t<_Is_simple_alloc_v<_Alty>, _Simple_types<_Ty>,_Vec_iter_types<_Ty, size_type, difference_type, pointer, const_pointer, _Ty&, const _Ty&>>>;public:using iterator = _Vector_iterator<_Scary_val>;using const_iterator = _Vector_const_iterator<_Scary_val>;using reverse_iterator = _STD reverse_iterator<iterator>;using const_reverse_iterator = _STD reverse_iterator<const_iterator>;上面的代碼從value_type到differrence_type,這些都是內嵌型別,用于泛化函數參數,返回值等。
_Alty_traits這個老朋友出現在了這里,通過它可以將allocator這個類中的內嵌型別給取出來。
接下來的_Vector_val這是個模板類,源碼如下:
emplate <class _Val_types> class _Vector_val : public _Container_base { public:using value_type = typename _Val_types::value_type;using size_type = typename _Val_types::size_type;using difference_type = typename _Val_types::difference_type;using pointer = typename _Val_types::pointer;using const_pointer = typename _Val_types::const_pointer;using reference = value_type&;using const_reference = const value_type&;_CONSTEXPR20_CONTAINER _Vector_val() noexcept : _Myfirst(), _Mylast(), _Myend() {}_CONSTEXPR20_CONTAINER _Vector_val(pointer _First, pointer _Last, pointer _End) noexcept: _Myfirst(_First), _Mylast(_Last), _Myend(_End) {}_CONSTEXPR20_CONTAINER void _Swap_val(_Vector_val& _Right) noexcept {this->_Swap_proxy_and_iterators(_Right);_Swap_adl(_Myfirst, _Right._Myfirst);_Swap_adl(_Mylast, _Right._Mylast);_Swap_adl(_Myend, _Right._Myend);}_CONSTEXPR20_CONTAINER void _Take_contents(_Vector_val& _Right) noexcept {this->_Swap_proxy_and_iterators(_Right);_Myfirst = _Right._Myfirst;_Mylast = _Right._Mylast;_Myend = _Right._Myend;_Right._Myfirst = nullptr;_Right._Mylast = nullptr;_Right._Myend = nullptr;}pointer _Myfirst; // pointer to beginning of arraypointer _Mylast; // pointer to current end of sequencepointer _Myend; // pointer to end of array };在_Vector_val的模板參數中,又看見了conditional_t這個結構體,它的功能我在上一章都說了。在這里,是為了判斷容器里的數據類型是用戶自定義類型,還是C++本身有的數據類型。
我們要知道,只有類或者結構體才能內嵌型別,像int,float這種是不行的,如果不能內嵌型別那么萃取器無法工作。所以為了實現這種要求,要將int等基本數據進行改造,在VS中是使用_Simple_types這個來創建的,_Simple_types代碼如下:
// STRUCT TEMPLATE _Simple_types template <class _Value_type> struct _Simple_types { // wraps types from allocators with simple addressing for use in iterators// and other SCARY machineryusing value_type = _Value_type;using size_type = size_t;using difference_type = ptrdiff_t;using pointer = value_type*;using const_pointer = const value_type*; };通過_Is_simple_alloc_v<_Alty>判斷是不是基本數據類型,如果是則使用_Simple_types包裝下,如果是用戶自定義的數據類型,則使用?_Vec_iter_types進行包裝,其代碼如下:
template <class _Value_type, class _Size_type, class _Difference_type, class _Pointer, class _Const_pointer,class _Reference, class _Const_reference> struct _Vec_iter_types {using value_type = _Value_type;using size_type = _Size_type;using difference_type = _Difference_type;using pointer = _Pointer;using const_pointer = _Const_pointer; };由于是用戶的自定義類型,所以需要從空間分配器類中找到對應的型別,就有如下的代碼:
using size_type = typename _Alty_traits::size_type;using difference_type = typename _Alty_traits::difference_type;using pointer = typename _Alty_traits::pointer;using const_pointer = typename _Alty_traits::const_pointer; //_Ty 就是你自定義的數據類型 _Vec_iter_types<_Ty, size_type, difference_type, pointer, const_pointer, _Ty&, const _Ty&>_Vec_iter_types代碼如下:
template <class _Value_type, class _Size_type, class _Difference_type, class _Pointer, class _Const_pointer,class _Reference, class _Const_reference> struct _Vec_iter_types {using value_type = _Value_type;using size_type = _Size_type;using difference_type = _Difference_type;using pointer = _Pointer;using const_pointer = _Const_pointer; };它跟之前的結構體不一樣,這個是需要好幾個參數。
? using _Scary_val = _Vector_val<conditional_t<_Is_simple_alloc_v<_Alty>, _Simple_types<_Ty>,_Vec_iter_types<_Ty, size_type, difference_type, pointer, const_pointer, _Ty&, const _Ty&>>>;
這個步驟完成后,接下來就要創建Vector的迭代器了,我就討論下兩個迭代器。代碼如下:
template <class _Myvec> class _Vector_iterator : public _Vector_const_iterator<_Myvec> { public:using _Mybase = _Vector_const_iterator<_Myvec>;#ifdef __cpp_lib_conceptsusing iterator_concept = contiguous_iterator_tag; #endif // __cpp_lib_conceptsusing iterator_category = random_access_iterator_tag;using value_type = typename _Myvec::value_type;using difference_type = typename _Myvec::difference_type;using pointer = typename _Myvec::pointer;using reference = value_type&;//成員函數略 };template <class _Myvec> class _Vector_const_iterator : public _Iterator_base { public: #ifdef __cpp_lib_conceptsusing iterator_concept = contiguous_iterator_tag; #endif // __cpp_lib_conceptsusing iterator_category = random_access_iterator_tag;using value_type = typename _Myvec::value_type;using difference_type = typename _Myvec::difference_type;using pointer = typename _Myvec::const_pointer;using reference = const value_type&;using _Tptr = typename _Myvec::pointer;//成員函數略 }這兩個迭代器的模板參數就是剛才的_Scary_val,_Scary_val中的模板參數就是conditional_t,層層嵌套,都快繞暈了。
通過這層別名設計,使得迭代器能指向對應類型的數據,從而實現泛化。
就這么多吧,自己本事不咋地,這個文章是我自己草稿用的,如有錯誤歡迎指正。
總結
以上是生活随笔為你收集整理的stl源码 vector不正规解析2 (自用)VS2019的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mac快捷键修改跟windows一样_如
- 下一篇: 2022-2027年中国服装定制行业市场