STL是如何订购容器的

How STL ordered containers know their end?

本文关键字:何订购 STL      更新时间:2023-10-16

我知道该标准并没有规定STL容器的实现方式,而是为每个容器规定了一组要求。

然而,众所周知,STL有序容器通常被实现为红黑树。

您可以使用std::setstd::map各自的迭代器对它们的元素进行迭代,或者从C++11开始使用范围循环。

然而,令我困惑的是,STL中的有序容器是如何"知道"的它的"结束"。或者换一种说法,因为它们被实现为树,容器的末端是如何实现的,或者它可能是实施?

我知道标准规定了§23.2.1/c一般集装箱要求Emphasis Mine):

begin()返回一个迭代器,该迭代器引用集装箱end()返回一个迭代器,该迭代器超过了结束值用于容器如果容器为空,则begin()==end();

好吧,对于连续的容器来说,这很容易,但这种"过去的结束"是如何为树实现的呢?

我刚刚检查了map容器在Visual Studio 2013 STL中的实现,下面是end的实现方式。当构造map时,RB树的头元素被分配,并且该元素被声明为容器的末尾。

当您通过有效的迭代器遍历容器时,operator++operator--只需跳过head元素。当你到达树的最后一个元素并增加迭代器时,它会向上爬(寻找右子树),最终到达树的头部,即end

所有像这样的"类似列表"的容器都需要有某种哨兵节点作为结尾,因为用户可以获得end(),在容器中插入一些东西,递减迭代器,递减的end()必须指向插入的元素。我的理解是,有些实现会为此进行动态分配,有些则会将动态sentinel节点放入容器本身。