紧接上一篇,我们接着看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 array
pointer _Mylast; // pointer to current end of sequence
pointer _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 machinery
using 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_concepts
using iterator_concept = contiguous_iterator_tag;
#endif // __cpp_lib_concepts
using 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_concepts
using iterator_concept = contiguous_iterator_tag;
#endif // __cpp_lib_concepts
using 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,层层嵌套,都快绕晕了。
通过这层别名设计,使得迭代器能指向对应类型的数据,从而实现泛化。
就这么多吧,自己本事不咋地,这个文章是我自己草稿用的,如有错误欢迎指正。
|