2017-03-08 90 views
1

所有這三個容器都通過const引用接受函數對象,而不是值或轉發引用。這導致需要將函數對象複製到容器的內部存儲器中(最多兩次)。std :: map,std :: set和std :: priority_queue中的比較器

是否有複製函數對象兩次的原因?與賦予用戶傳遞任何類型的函數對象並將其構建到內部函子存儲中的能力相反?這樣,圖書館就更加普遍,對用戶而言意想不到。


相同的理念是在push_back()功能施加 - 它們具有兩個重載,一個具有const引用和一個與一個rvalue參考,因爲這爲用戶提供了關於他們是否希望移動的值或複製多個控制價值。在一般情況下,圖書館保持高效率,而不會對用例做任何假設。

我懷疑這是一個設計決定,自從C++之前的11天以來一直在繼續。改變這是標準的體面提案嗎?

回答

0

通常,比較器是一個非常小的對象,便於複製,而且您只需構建一次容器。額外的一次複製一次不是真的要去做。您可能不會在延遲敏感的代碼中創建一堆std::map。因此,爲這些容器引入更多構造函數並沒有太多好處。這樣的提案會是什麼樣子?那麼你會想通過右值引用參考Allocator嗎?現在我們添加了更多的構造函數。改變所有構造函數採取Compare const&而不是採取約束轉發引用?現在,我們打破了ABI仍然邊緣,如果有的話,獲得。構造函數很複雜。我甚至不相信,如果今天設計了std::map,那麼界面在這方面看起來會有所不同。如果有的話,我們可能只需要Compare而不是const&

另一方面,在主程序運行期間,push_back被用於各種類型的LOT。能夠將vectoremplace轉換爲vector,是一個巨大的勝利。這兩種情況並沒有真正的可比性。

+0

爲什麼std :: thread構造函數接受一個由rvalue引用的函子?如果它只是在內部複製它?而且我們不會添加更多的構造函數,它只是將現有構造函數更改爲通過轉發引用來接受參數。雖然我不確定這是否會破壞事物。 – Curious

+0

@Curious'thread'有一個構造函數,它具有任意函數。 'map'有4個構造函數,它們需要一個'Compare'或一個'Allocator' - 你必須改變它們,這更復雜一些,並且打破ABI。 – Barry

+0

這究竟是如何打破ABI?當你傳遞一個非右值時,比較器就會像以前一樣被複制。 – Curious