2016-12-05 56 views
3

我目前看STL库,我想知道为什么一个Vector类vector<string> names;我要叫remove();如下:为什么STL算法针对不同类别调用不同?

names.erase(remove(names.begin(), names.end(), "Simon"), names.end()); 

使用列表类list<string> names;时,虽然我可以调用函数如下:

remove("Simon"); 

我也注意到了reverse();同为vector<string> names;它被称为如下:

reverse(names.begin(), names.end()); 

虽然list<string> names;它被称为如下:

names.reverse(); 

是它更适合于随时拨打方式矢量会吗?为什么是这样?我对C++非常陌生,所以我很想知道做事情的最佳方式。

+0

请参阅[list.sort和stl之间的区别是什么?](http://stackoverflow.com/questions/8017215/whats-the-difference-between-list-sort-and-stdsort)简而言之:当算法可以更有效地实现这些类时,这个算法可以访问类的内部,而不是通过单独提供的迭代器来处理。一般语法只授予对接口的访问权限。成员函数调用可以使用内部。 – jaggedSpire

+4

*“我对C++非常陌生”*这解释了为什么您期望在C++中命名是合理的。 ;)另外两个有趣的位:'std :: remove_copy_if'不会删除任何东西,并且在'char'上调用'std :: toupper'可能调用UB。欢迎来到C++。 :) –

+0

@ n.m。我知道,删除是为了在删除内部调用,我想知道为什么。即使我不在擦除内部调用,它仍然需要不同的格式。 – stuart194

回答

7

基本上,有一些特殊情况与特定容器的性质有关。

一般而言std::removestd::remove_if,和std::reverse<algorithm>头部声明的自由功能将通过复制和移动元件上的载体,列表,双端队列,和数组。 (当然,他们不会在集合或地图上工作,因为对于那些不能自由重新排列元素的人来说)。请注意,std::remove不会从容器中删除元素。

一般每个容器类型的成员函数erase用于从该容器中删除元素。 (请注意,std::array没有erase,因为它的大小是固定的。)

特殊情况:

  • std::list提供reverse,作为成员因为只有成员函数可以保证它不会使任何迭代器失效;通用std::reverse不能。
  • removeremove_if也是如此,虽然名称具有误导性,因为与免费功能不同,成员从列表中删除元素。
  • 还有一个成员sortstd::list,因为通用std::sort只适用于随机访问迭代器。
  • 对于套和地图,我们应利用其成员lower_boundupper_boundequal_rangecount,而不是通用版本,因为他们知道怎么走下来的树,得到的结果是对数时间,而免费的功能将使用线性时间。

通常,原理似乎是:标准库容器尽可能支持统一接口,但也提供额外的专用函数以提供依赖其内部的功能。

+0

感谢您对此发表看法!所以当我使用一个列表类时,通常最好称它们为我所显示的那样? – stuart194

+0

@ stuart194是的,我认为您应该在适用时通常使用容器特定的功能。 – Brian

相关问题