2016-12-05 70 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

相關問題