在标准容器中实现大小

时间:2011-08-22 08:46:21

标签: c++ stl

这是一个纯理论问题,我知道标准容器界面现在不太可能改变......

我最近读了一本Herb Sutter“本周的大师”,他抱怨说empty()在std::string中被实现为成员函数。我不同意所有的论点,因为例如std::list需要对同一函数执行不同的实现,因为size()是O(n),而empty()显然是O(1)。

但是,有没有理由为什么标准指定(例如)std::string的empty()成员函数实现为"size () == 0"而不是"begin () == end ()"

在我看来,后者允许对所有容器使用empty()函数的相同O(1)实现,我想不出任何缺点。它的效率会降低吗?

谢谢,

N.G。

4 个答案:

答案 0 :(得分:4)

标准未指定完全库中的任何内容的实现方式。它只是指明某事物的含义。因此,如果empty()为真,则size()也必须为0.这并不意味着empty()必须实际调用std::basic_string::size()并将其与0进行比较。规范只是说如果empty()返回true,则紧接着调用size()将返回0,如果empty()返回false,则在<{1}}之后立即调用<{1}} em> not 返回0。

规范可以说它的size()将等于它的begin(),并且它会迫使没有实现更改。

不一致很可能是end()类在C ++ 98开发过程中来自其他STL容器的不同位置的结果。这就是为什么它有很多成员函数来处理STL容器通常用算法做的事情。

答案 1 :(得分:2)

empty()size() == 0等效的规范不应按字面意思理解。代码片段仅显示函数的意图,而不是它们的实现方式。

我在另一个论坛上向委员会成员证实了这一点。

在您的示例中,size()也可能实现为end() - begin()的等效项,因此无论如何都可能没有区别。

答案 2 :(得分:0)

是的,因为string :: end()通常被实现为像return (_STRING_ITERATOR(_Myptr() + this->_Mysize));

那样效率会低一些

因此,使用size()== 0可以减少添加的需要。

答案 3 :(得分:0)

Herb建议使length()使用size()实现非成员函数,并与empty()等效:

  

长度()怎么样?容易,再次 - 它被定义为给出与size()相同的结果。更重要的是,请注意其他容器没有length(),并且它在basic_string接口中作为一种“字符串事物”存在,但是通过使它成为非成员突然我们可以简单地说“length()”关于任何容器。在这种情况下不太有用,因为它只是size()的同义词,我授予你,但它所说明的原则中值得注意的一点 - 立即使算法非成员也使它们更有用和可用。

size()作为成员函数的原因是,在大多数情况下,实现将缓存计算成本高昂的容器的值(即对于列表或映射,存储包含的元素的数量在容器本身以避免必须走结构),以符合size应该是O(1)操作(§23.1/ 5)的标准中的建议。