std :: map如何提供常量size()操作?

时间:2015-01-10 01:03:15

标签: c++ c++11 stl

我知道除了size()之外,所有容器都提供常量forward_list操作。但是map,其内部数据结构是红黑树,如何以恒定的复杂性提供size()?对于像vector和string这样的其他人也一样。他们用柜台吗?如果是这样,为什么不forward_list

当我读到 c ++标准库:教程和参考这本书时,我很困惑。

1 个答案:

答案 0 :(得分:64)

这是一个漫长而扭曲的故事。 : - )

是,map,set,list等保持计数器提供一个恒定的时间size()。在C ++ 11之前,没有一个容器需要保留计数器,因为它们的size() 应该是恒定时间,但不是 是恒定时间。在标准中,“应该”意味着可能,也许不是,“必须”意味着绝对。

实际上,在C ++ 98/03中,所有容器都有一个恒定的时间size()list除外,甚至mapset(使用计数器) )。这为使用list的一些可怕的非可移植代码做了准备,其中一些假设了一个恒定的时间size(),其中一些假设了一个恒定的时间"splice some from other."这两个操作都不能是恒定的时间,实现必须选择其中一个。

在C ++ 11中,标准被改为说size()必须是恒定时间。但是forward_list同时也被引入。 forward_list的重点是list的优化。委员会不想重复list::size()的错误,有时是不变的时间,有时是线性时间。所以决定不给forward_list一个size()。因此,客户永远不会成为意外线性时间size()的受害者。 forward_list想要进行此项计算的客户如果选择这样做,仍然可以使用distance(fl.begin(), fl.end())

有关从size()省略forward_list的理由的详细信息,请参阅N2543