紧接上一篇,我们接着看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相关推荐

  1. Faster R-CNN源码中RPN的解析(自用)

    参考博客(一定要看前面两个) 一文看懂Faster R-CNN 详细的Faster R-CNN源码解析之RPN源码解析 关于RPN一些我的想法 rpn的中心思想就是在了anchors了,如何产生anc ...

  2. STL源码剖析 空间配置器 查漏补缺

    ptrdiff_t含义 减去两个指针的结果的带符号整数类型 ptrdiff_t (Type support) - C 中文开发手册 - 开发者手册 - 云+社区 - 腾讯云 std::set_new_ ...

  3. 必不可少!STL源码目录结构分析,附加源码下载链接

    一.STL源码的下载 下载地址1 3种下载方式: 公众号[多栖技术控小董]回复[12754727]获取百度云下载链接. CSDN:https://download.csdn.net/download/ ...

  4. C++ STL源码剖析 笔记

    写在前面 记录一下<C++ STL源码剖析>中的要点. 一.STL六大组件 容器(container): 各种数据结构,用于存放数据: class template 类泛型: 如vecto ...

  5. 【有点狂的手撕STL】STL源码剖析精读 000

    STL源码剖析精读 前言 通过刷题感受到了C++中STL的妙用,十分的想要提高自己对于STL的理解以及运用能力,因此开设此专栏,并希望能够带领大家一起感受C++中STL的魅力. 一.STL简介 STL ...

  6. STL源码剖析—stl_config

    操作系统:centos 6.4 STL源码版本:3.3 前言:     要看一个项目的源码,首先要选中切入点.     那么在sgi stl 标准库中,其切入点是什么呢?     答案是:stl_co ...

  7. C++ Standard Stl -- SGI STL源码学习笔记(07) stl_vector 与 一些问题的细化 3 resize函数剖析...

    前面在介绍push_back函数的时候有说到placement new的用法.前面说的很简单.这几天处理一些其他的事情,直到昨天下午 才有时间看源码,顺便安静的看一下书. 其中我又看到了挂关于plac ...

  8. STL源码剖析面试问题

    当vector的内存用完了,它是如何动态扩展内存的?它是怎么释放内存的?用clear可以释放掉内存吗?是不是线程安全的? vector内存用完了,会以当前size大小重新申请2* size的内存,然后 ...

  9. [转载]《STL源码剖析》阅读笔记之 迭代器及traits编程技法

    本文从三方面总结迭代器   迭代器的思想   迭代器相应型别及traits思想   __type_traits思想 一 迭代器思想 迭代器的主要思想源于迭代器模式,其定义如下:提供一种方法,使之能够依 ...

  10. STL源码剖析 数值算法 copy 算法

    copy复制操作,其操作通过使用assignment operator .针对使用trivial assignment operator的元素型别可以直接使用内存直接复制行为(使用C函数 memove ...

最新文章

  1. Ubuntu 系统禁止或者改变中文简体切换繁体,方便使用AS全局搜索
  2. 生成器和生成器表达式
  3. WebSocket——stomp连接错误[Whoops! Lost connection to XXX]解决方案
  4. 【Gym - 101612C】【2017-2018NEERC】Consonant Fencity(状压枚举,预处理)
  5. Typecho网站隐藏内容公众号验证码查看涨粉丝插件(美化版)
  6. 仓库对象DataSet与小车对象DataAdapter的 关键命令 1201
  7. python编写音乐标签_如何用PYTHON代码写出音乐
  8. 计算机网络原理视频学习教程
  9. wince驱动加载失败
  10. Android ELF文件编译之符号隐藏
  11. Lucas-Kanade 算法原理以及应用
  12. 大学生慕课网站计算机操作系统,中国大学mooc电脑版
  13. 3D汽车作品大赏!汇集世界各地CG大佬们的“汽车梦”
  14. Verilog学习总结
  15. 嵌入式系统自动化测试工具
  16. 三维实现广州的行政区划
  17. 桌面上计算机删除后怎么复原,电脑桌面上出现一个图标,删掉后重启桌面又恢复了?怎么才能彻底删除?...
  18. yyyymmddhhmmss时间格式12小时制24小时制区别
  19. 什么是PCB Testpoints
  20. js 获取本月/本周第一天和最后一天,封装并在小程序引用

热门文章

  1. Sentinel系统自适应限流【原理源码】
  2. mp3lame linux 编译,ubantu-16+ndk-r14b 编译 ffmpeg-4.0.2+lame_mp3-3.99.5
  3. 【物联网+GIS】让传感器数据在三维地图上显示,更直观,更震撼!
  4. 隆重推荐:吴闲云 - 三国中的博弈
  5. 做SEO优化第九步:如何设置页面内容优化
  6. 页面视觉稳定性之优化CLS
  7. 相信我,我们离成为废物阶级不远了!
  8. WORD2013使用技巧——调整序号中制表位的大小
  9. 威联通NAS网络存储器快速安装指南——从零搭建一个文件存储平台
  10. 如何在计算机自动开机时选择用户,电脑如何设置自动开机