C++ bits/stl_tree.h中的_Rb_tree_增量的定义是什么?

C++ bits/stl_tree.h中的_Rb_tree_增量的定义是什么?,c++,algorithm,stl,C++,Algorithm,Stl,我想学习stl中红黑树的代码。我在bits/stl_tree.h文件中找到了一个名为_Rb_tree_increment的函数 它写道: 143 _GLIBCXX_PURE _Rb_tree_node_base* 144 _Rb_tree_increment(_Rb_tree_node_base* __x) throw (); 但是我找不到这个函数的定义。有人能帮忙吗 非常感谢。该定义取决于您拥有的标准库。不同的编译器供应商在其编译器中提供标准库的不同实现。您似乎找到了一个非模板函

我想学习stl中红黑树的代码。我在bits/stl_tree.h文件中找到了一个名为_Rb_tree_increment的函数

它写道:

 143   _GLIBCXX_PURE _Rb_tree_node_base*
 144   _Rb_tree_increment(_Rb_tree_node_base* __x) throw ();
但是我找不到这个函数的定义。有人能帮忙吗


非常感谢。

该定义取决于您拥有的标准库。不同的编译器供应商在其编译器中提供标准库的不同实现。您似乎找到了一个非模板函数。这应该在一些cpp中定义,并且它将随编译器在lib文件中提供,因此您不能直接访问代码,因为它不会随编译器提供-这根本不是必需的


如果您的编译器是一个适当的编译器,例如来自Microsoft或Borland的编译器,那么您将得到这些。但是,如果您有一个gcc,那么您就幸运了:gcc是开源的,您可以在线找到标准库的gcc实现的源代码

它将出现在库的源代码中,而您可能没有


看起来您正在查看GNU库的标题,因此这是开始查找源代码的好地方。

正如@Mike Seymour所说,我在库的源代码路径上找到了定义,更准确地说是在
gcc-4.8.1/libstdc++-v3/src/c++98/tree.cc中:

  static _Rb_tree_node_base*
  local_Rb_tree_increment(_Rb_tree_node_base* __x) throw ()
  {
    if (__x->_M_right != 0) 
      {
        __x = __x->_M_right;
        while (__x->_M_left != 0)
          __x = __x->_M_left;
      }
    else 
      {
        _Rb_tree_node_base* __y = __x->_M_parent;
        while (__x == __y->_M_right) 
          {
            __x = __y;
            __y = __y->_M_parent;
          }
        if (__x->_M_right != __y)
          __x = __y;
      }
    return __x;
  }

  _Rb_tree_node_base*
  _Rb_tree_increment(_Rb_tree_node_base* __x) throw ()
  {
    return local_Rb_tree_increment(__x);
  }

  const _Rb_tree_node_base*
  _Rb_tree_increment(const _Rb_tree_node_base* __x) throw ()
  {
    return local_Rb_tree_increment(const_cast<_Rb_tree_node_base*>(__x));
  }
static\u Rb\u tree\u node\u base*
本地\u Rb\u树\u增量(\u Rb\u树\u节点\u基*\uuux)抛出()
{
如果(uuu x->u M_right!=0)
{
__x=\uuuux->\um\u right;
而(uuu x->u M_左!=0)
__x=\uuuuX->\uM\u左;
}
其他的
{
_Rb_树_节点_基*u y=uu x->_M_父节点;
而(\uuuux==\uuuu y->\u M\u right)
{
__x=uuy;
__y=uuu y->u M_u父项;
}
如果(uuu x->u M_right!=\uu y)
__x=uuy;
}
返回x;
}
_Rb_树_节点_基*
_Rb_树\u增量(_Rb_树\u节点\u基*\uuux)抛出()
{
返回局部树增量(uux);
}
常数Rb树节点基*
_Rb_树增量(常量Rb_树节点Rb_基*ux)抛出()
{
返回局部Rb树增量(常量转换(uux));
}

OP显然是在使用GCC附带的stdlibc++实现。非常感谢,Arne,您的回答切中要害(“您似乎找到了一个非模板函数。它应该在一些cpp中定义,并且将随编译器在lib文件中提供”):)谢谢,迈克。你的链接非常有用。:)@RaGrdl看来,“增量”是C++的“迭代器::运算符+”,它将转换为“兄弟”,注意“减量”是相反的操作(指向我的先驱兄弟)这在维基百科的页面上没有定义。看看第二个
if
语句:
\uuuuux->\um\u right
怎么可能等于
\uuuu y
(即它的祖父母)?@user2023370我也被这种情况弄得很复杂。我认为这是一个狡猾的漏洞。正如您在上面的while语句中所看到的,
x
可以“向上爬”到根,但是
\uuuuuuy=\uuuuuuy->\um\u parent
。如果
x
是根,为什么可以检查
\uuux==\uu y->\u M\u right
?这意味着根的父级不是
nullptr
?在我看来,根的父级似乎是它的左子级(也许,我不确定)@user2023370如果你查看相反函数的源代码,\u Rb\u tree\u decrement(),你实际上会在那里找到以下代码:
If(…\uuuuuux->\u M\u parent->\u M\u parent=\ux)
。是的,对于根元素,元素的祖辈可以是元素本身。这可能是为了维护指向树的第一个和最后一个元素的特殊指针,以便
begin()
end
std::prev(end)
都是有效的,不需要分别在树中筛选以找到第一个或最后一个元素。@user2023370通过查看
\u Rb\u tree\u insert\u和\u rebalance()
,我们可以看到,
\u header.\u M\u parent
实际上是指根节点,而
\u header.\u M\u left
\u header.\u M\u right
分别指最左边的节点(
begin()
)和最右边的节点(
std::prev(end())
)。
\u header()
节点本身表示
end()
迭代器。您已经看到的特殊条件可能存在,因此
operator++
operator--
实际上不会超过开头/结尾。