STL中forward-list大致实现
1.std::array<_Tp,std::size_t>
源代码仔细看一下就知道了:/usr/include/c++/9/array
挑出来的大致实现:
主要的就是和traits(编译期传递类型)的配合,
可以看到std::array的内存分配就是在栈上的,没有使用分配器std::allocator,
对个数0特化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <iostream> #include <array>
#include <ext/aligned_buffer.h> #include <bits/alloc_traits.h> #include <bits/allocator.h>
namespace llc { template<typename _Tp,std::size_t _Nm> struct __array_traits { typedef _Tp _Type[_Nm]; };
template<typename _Tp> struct __array_traits<_Tp,0> { struct _Type {}; };
template<typename _Tp,std::size_t _Nm> struct array { typedef _Tp value_type; typedef value_type* pointer; typedef value_type& reference; typedef const value_type* const_pointer; typedef const value_type& const_reference; typedef value_type* iterator; typedef const value_type* const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef __array_traits<_Tp,_Nm> _AT_Type;
typename _AT_Type::_Type _M_elems;
}; }
int main() { std::array<int,10> ar1; std::cout << "int-size: " << sizeof(int) << " std::array-size " << sizeof(ar1) << "\n";
}
|
2.std::forward_list<_Tp,_Alloc>
1. gcc4.9的实现是从视频看到的
2.gcc9.3的实现是看源代码的
看起来大致结构是一样的
抽出来的源代码,解释在注释部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| #include <iostream> #include <array>
#include <ext/aligned_buffer.h> #include <bits/alloc_traits.h> #include <bits/allocator.h>
namespace llc { template<typename _TP> struct _Fwd_list_node_base { _Fwd_list_node_base *_M_next; }; template<typename _Tp> struct _Fwd_list_node:public _Fwd_list_node_base<_Tp> { _Tp M_value; };
template<typename _Tp> struct _Fwd_list_impl:public std::allocator<_Fwd_list_node<_Tp>> { _Fwd_list_node_base<_Tp> _M_head; };
template<typename _Tp> struct _Fwd_list_base { _Fwd_list_impl<_Tp> _M_impl; };
template<typename _Tp> struct forward_list:private _Fwd_list_base<_Tp> { }; }
namespace llc2 { struct _Fwd_list_node_base { _Fwd_list_node_base *_M_next = nullptr; };
template<typename _Tp> struct _Fwd_list_node:public _Fwd_list_node_base { __gnu_cxx::__aligned_buffer<_Tp> _M_storage; }; template<typename _Tp> struct _Fwd_list_iterator { typedef _Fwd_list_iterator<_Tp> _Self; typedef _Fwd_list_node<_Tp> _Node;
typedef _Tp value_type; typedef _Tp* pointer; typedef _Tp& reference; typedef std::ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; _Fwd_list_node_base *_M_node; };
template<typename _Tp> struct _Fwd_list_const_iterator { typedef _Fwd_list_const_iterator<_Tp> _Self; typedef const _Fwd_list_node<_Tp> _Node; typedef _Fwd_list_iterator<_Tp> iterator;
typedef _Tp value_type; typedef const _Tp* pointer; typedef const _Tp& reference; typedef std::ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category;
const _Fwd_list_node_base* _M_node; }; template<typename _Tp,typename _Alloc> struct _Fwd_list_base { protected:
typedef std::__alloc_rebind<_Alloc,_Fwd_list_node<_Tp>> _Node_alloc_type; typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
struct _Fwd_list_impl:public _Node_alloc_type { _Fwd_list_node_base _M_head; };
_Fwd_list_impl _M_impl; public: typedef _Fwd_list_iterator<_Tp> iterator; typedef _Fwd_list_const_iterator<_Tp> const_iterator; typedef _Fwd_list_node<_Tp> _Node;
};
template<typename _Tp,typename _Alloc=std::allocator<_Tp>> class forward_list:private _Fwd_list_base<_Tp,_Alloc> { private: typedef _Fwd_list_base<_Tp,_Alloc> _Base; typedef _Fwd_list_node_base _Node_base; typedef typename _Base::_Node _Node; typedef typename _Base::_Node_alloc_type _Node_alloc_type; typedef typename _Base::_Node_alloc_traits _Node_alloc_traits; typedef std::allocator_traits<std::__alloc_rebind<_Alloc,_Tp>> _Alloc_traits;
public: typedef _Tp value_type; typedef typename _Alloc_traits::pointer pointer; typedef typename _Alloc_traits::const_pointer const_pointer; typedef value_type& reference; typedef const value_type& const_reference;
typedef typename _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef _Alloc allocator_type; }; }
int main() { llc::forward_list<int> f1; std::cout << "forward-list: " << sizeof(f1) << " pointer-size " << sizeof(int*) <<"\n";
llc2::forward_list<int> f2; std::cout << sizeof(f2); }
|