为什么stl_tree.h中的end()返回对迭代器对象的引用,而begin()返回object ?
Why does end() in stl_tree.h return a reference to the iterator object but begin() returns object?
在GCC stl_tree.h:
https://gcc.gnu.org/onlinedocs/libstdc + +/libstdc + + html -用户- 4.1/stl__tree_8h-source.html
begin()
和end()
返回迭代器对象。然而,end()
返回对象的地址,而begin()
返回对象本身。
- 为什么会有这种差异?
- 是否
begin()
返回一个对象意味着另一块内存需要被访问,内存中包含迭代器对象的值传递?
..............
00589 iterator begin()
00590 {
00591 return iterator(static_cast<_Link_type>
00592 (this->_M_impl._M_header._M_left));
00593 }
00594
00595 const_iterator
00596 begin() const
00597 {
00598 return const_iterator(static_cast<_Const_Link_type>
00599 (this->_M_impl._M_header._M_left));
00600 }
00601
00602 iterator
00603 end()
00604 { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }
00605
00606 const_iterator
00607 end() const
00608 {
00609 return const_iterator(static_cast<_Const_Link_type>
00610 (&this->_M_impl._M_header));
}
地点:
typedef _Rb_tree_iterator<_Tp> iterator;
typedef _Rb_tree_const_iterator<value_type> const_iterator;
:
template<typename _Tp>
00221 struct _Rb_tree_const_iterator
00222 {
00223 typedef _Tp value_type;
00224 typedef const _Tp& reference;
00225 typedef const _Tp* pointer;
00226
00227 typedef _Rb_tree_iterator<_Tp> iterator;
00228
00229 typedef bidirectional_iterator_tag iterator_category;
00230 typedef ptrdiff_t difference_type;
00231
00232 typedef _Rb_tree_const_iterator<_Tp> _Self;
00233 typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr;
00234 typedef const _Rb_tree_node<_Tp>* _Link_type;
00235
00236 _Rb_tree_const_iterator()
00237 : _M_node() { }
00238
00239 explicit
00240 _Rb_tree_const_iterator(_Link_type __x)
00241 : _M_node(__x) { }
00242
00243 _Rb_tree_const_iterator(const iterator& __it)
00244 : _M_node(__it._M_node) { }
00245
00246 reference
00247 operator*() const
00248 { return static_cast<_Link_type>(_M_node)->_M_value_field; }
00249
00250 pointer
00251 operator->() const
00252 { return &static_cast<_Link_type>(_M_node)->_M_value_field; }
00253
00254 _Self&
00255 operator++()
00256 {
00257 _M_node = _Rb_tree_increment(_M_node);
00258 return *this;
00259 }
00260
00261 _Self
00262 operator++(int)
00263 {
00264 _Self __tmp = *this;
00265 _M_node = _Rb_tree_increment(_M_node);
00266 return __tmp;
00267 }
00268
00269 _Self&
00270 operator--()
00271 {
00272 _M_node = _Rb_tree_decrement(_M_node);
00273 return *this;
00274 }
00275
00276 _Self
00277 operator--(int)
00278 {
00279 _Self __tmp = *this;
00280 _M_node = _Rb_tree_decrement(_M_node);
00281 return __tmp;
00282 }
00283
00284 bool
00285 operator==(const _Self& __x) const
00286 { return _M_node == __x._M_node; }
00287
00288 bool
00289 operator!=(const _Self& __x) const
00290 { return _M_node != __x._M_node; }
00291
00292 _Base_ptr _M_node;
00293 };
:
template<typename _Tp>
00151 struct _Rb_tree_iterator
00152 {
00153 typedef _Tp value_type;
00154 typedef _Tp& reference;
00155 typedef _Tp* pointer;
00156
00157 typedef bidirectional_iterator_tag iterator_category;
00158 typedef ptrdiff_t difference_type;
00159
00160 typedef _Rb_tree_iterator<_Tp> _Self;
00161 typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
00162 typedef _Rb_tree_node<_Tp>* _Link_type;
00163
00164 _Rb_tree_iterator()
00165 : _M_node() { }
00166
00167 explicit
00168 _Rb_tree_iterator(_Link_type __x)
00169 : _M_node(__x) { }
00170
00171 reference
00172 operator*() const
00173 { return static_cast<_Link_type>(_M_node)->_M_value_field; }
00174
00175 pointer
00176 operator->() const
00177 { return &static_cast<_Link_type>(_M_node)->_M_value_field; }
00178
00179 _Self&
00180 operator++()
00181 {
00182 _M_node = _Rb_tree_increment(_M_node);
00183 return *this;
00184 }
00185
00186 _Self
00187 operator++(int)
00188 {
00189 _Self __tmp = *this;
00190 _M_node = _Rb_tree_increment(_M_node);
00191 return __tmp;
00192 }
00193
00194 _Self&
00195 operator--()
00196 {
00197 _M_node = _Rb_tree_decrement(_M_node);
00198 return *this;
00199 }
00200
00201 _Self
00202 operator--(int)
00203 {
00204 _Self __tmp = *this;
00205 _M_node = _Rb_tree_decrement(_M_node);
00206 return __tmp;
00207 }
00208
00209 bool
00210 operator==(const _Self& __x) const
00211 { return _M_node == __x._M_node; }
00212
00213 bool
00214 operator!=(const _Self& __x) const
00215 { return _M_node != __x._M_node; }
00216
00217 _Base_ptr _M_node;
00218 };
没有对象在.end()
;它不存在。这是一个"越过终点"的迭代器。因此,.end()
必须使用可识别的"哨兵值"来实现,这就是您在这里看到的。
(另外,请注意它是&this->_M_impl._M_header
,而不是&this->_M_impl._M_header._M_left
!)
一个非常松散的类比是在c -string结尾找到的NULL
字符,当然在这种情况下你会发现NULL
值在适当的位置。
可以说,树可以实现这样,它总是有至少一个隐藏在前端接口的节点,它可以使用这个节点作为end()
;然后这些函数看起来会更像您所期望的,但它不会非常有效,您根本不会获得任何东西。
相关文章:
- 寿命延长从函数返回引用
- 了解C++如何返回引用并绑定到引用
- 返回引用实例和非引用实例(return mystr & vs mystr)之间的区别是什么?
- 从类返回引用向量
- 使用unique_ptr并返回引用,或者我应该使用shared_ptr并在需要时制作副本
- 混淆C++从函数返回引用
- 两个相同的重载运算符[]一个返回引用
- 为什么向量的.at()成员函数返回引用而不是迭代器
- C++使用和返回引用
- 返回 T 引用的 Const 函子禁止赋值
- 返回引用是否也会延长其生存期?
- 如何返回引用,然后递增迭代器
- 如果使用返回引用的函数初始化"auto"var,为什么它不声明引用类型?
- 我是否需要将 ref 与 make_pair 一起使用才能返回引用?
- 在 vector::at 返回引用后进行更改
- 为什么PyImport_ImportModule返回引用计数为 3 而不是 1 的 PyObject*
- 超出返回引用的单一实例生存期
- Boost.Python 返回引用现有 c++ 对象的 python 对象
- C++ 运算符 += 重载返回引用
- 如何声明接受转发引用并返回引用或副本的函数模板