我知道除了size()
之外,所有容器都提供常量forward_list
操作。但是map
,其内部数据结构是红黑树,如何以恒定的复杂性提供size()
?对于像vector和string这样的其他人也一样。他们用柜台吗?如果是这样,为什么不forward_list
?
当我读到 c ++标准库:教程和参考这本书时,我很困惑。
答案 0 :(得分:64)
这是一个漫长而扭曲的故事。 : - )
是,map,set,list等保持计数器提供一个恒定的时间size()
。在C ++ 11之前,没有一个容器需要保留计数器,因为它们的size()
应该是恒定时间,但不是 是恒定时间。在标准中,“应该”意味着可能,也许不是,“必须”意味着绝对。
实际上,在C ++ 98/03中,所有容器都有一个恒定的时间size()
,list
除外,甚至map
和set
(使用计数器) )。这为使用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。