2013-04-29 67 views
4

我明白为什么std::forward_listdoes not have a size() member function,因为O(1)版本会弄乱某些splice()过载的复杂性,并且因为O(N)版本会与标准库的其余所有容器不一致。为什么不是std :: forward_list给定一个count()成员函数?

,这也是事实,无论std::liststd::forward_list已经拥有相同的语义从<algorithm>角落标准库(merge()reverse()remove()remove_if()unique()sort())的他们的堂兄弟其他几个成员函数。

那么为什么count()成员函数的O(N)复杂度提供给std::forward_list,它的返回语义是std::distance(std::begin(some_list), std::end(some_list))

+0

基本上,STL类已经足够大了,并且在其中一个上添加这样的成员函数会触发用户需要的所有其他STL容器中的东西。而且,正如你所说(在提案中已经提到过),'std :: distance'可以在没有更多时间的情况下获得大小,所以几乎没有什么伤害。 – Morwenn 2013-04-29 13:35:30

+0

@Morwenn,但不需要在任何其他容器中都有count(),因为它们都已经有size()。 – TemplateRex 2013-04-29 13:36:50

+0

@rhalbersma:因为我们已经有'std :: distance()',所以不需要在任何容器中都有count()。 – 2013-04-29 13:38:06

回答

10

你提到的成员函数(merge()reverse()remove()remove_if()unique()sort())提供,因为他们有更好的比<algorithm>标准头通用算法的复杂性。

另一方面,成员函数count()的复杂度不会比std::distance(std::begin(some_list), std::end(some_list))更好。

此外,它可能会被误解为std::count泛型算法的更好复杂版本,它会做一些基本上不同的操作。

+0

属实,这将是一个方便的功能,就像'的std ::开始()'/'的std ::结束()''为std :: array' – TemplateRex 2013-04-29 13:37:59

+3

@rhalbersma:'std :: begin()'和'std :: end()'不仅仅是一种方便;他们提供了一个通用的方式来获得可迭代的容器,包括数组的边界。 – 2013-04-29 13:39:32

+2

对于'std :: count' +1。 – Morwenn 2013-04-29 13:42:30

3

原因是因为,与您列出的函数不同,使用标准库算法进行计数或大小函数的速度与直接访问底层实现的版本一样快。

您为std::forward_list提到的每个成员函数实际上都是更快的成员。尤其是,它们可以在不执行任何不必要的复制或移动所包含数据的情况下运行。标准库算法版本要求复制或移动容器中的数据。

相关问题