我知道标准并没有规定必须实施STL容器的方式,而是规定了每个容器的一系列要求。
然而,众所周知,STL有序容器通常实现为red–black trees。
您可以使用各自的迭代器遍历std::set
或std::map
的元素,或者使用远程循环来迭代C ++ 11。
然而令我感到困惑的是,STL中有序容器如何“知道” 它的“结束”。换句话说,因为它们被实现为树木, 如何实现容器的结束或者它是如何实现的 执行吗?
我知道标准规定了§23.2.1/ c一般容器要求( Emphasis Mine ):
begin()返回一个迭代器,引用该中的第一个元素 容器。 end()返回一个迭代器,它是一个过去的结束值 对于容器。如果容器为空,则begin()== end();
好的,对于连续的容器来说,这很容易,但这种“过去的结果”如何实现树木?
答案 0 :(得分:9)
我刚刚在Visual Studio 2013 STL中检查了map
容器的实现,以下是end
的实现方式。构造map
时,将分配RB树的head元素,并将此元素声明为容器的末尾。
当您通过有效迭代器遍历容器时,operator++
和operator--
只需跳过head元素。当你到达树的最后一个元素并递增一个迭代器时,它会向上爬(寻找一个正确的子树)并最终到达树的头部,即end
。
答案 1 :(得分:3)
所有"类似列表"像这样的容器需要有一些终结节点,因为用户可以得到end()
,在容器中插入一些东西,递减迭代器,并且递减的end()
必须指向插入的元素。我的理解是,有些实现会为此动态分配,有些实现会将动态sentinel节点放在容器本身内。