簡體   English   中英

std :: unordered_map :: insert的重載

[英]overload of std::unordered_map::insert

你能教我兩者嗎?

std::unordered_map::insert(const value_type&)

template<class P> std::unordered_map::insert(P&&)

存在於標准中?

我認為insert(P&&)可以作為insert(const value_type&)

這兩個都是重載

auto std::unordered_map::insert(const value_type&) -> ...

template<class P>
auto std::unordered_map::insert(P&&) -> ...

有自己的優勢,也不能完全取代對方。 第一個似乎是第二個的特例,因為P可能被推導為const value_type& 關於第二次重載的好處是你可以避免不必要的副本。 例如,在這種情況下:

mymap.insert(make_pair(7,"seven"));

這里,make_pair的結果實際上是一pair<int, const char*>value_type可能是pair<const int, string> 因此,我們不是創建臨時的value_type對象並將其復制到容器中,而是通過轉換參數和/或移動其成員,直接在地圖中創建value_type對象。

另一方面,如果這樣做也會很好:

mymap.insert({7,"seven"});

但這個清單實際上不是表達! 因此,編譯器無法推斷出第二次重載的P. 第一個重載仍然可行,因為您可以使用這樣的列表復制初始化一pair<const int,string>參數。

n1858中添加了模板通用引用重載,具有基本原理(對於map ,但同樣明確適用於multimap ):

其中兩個insert簽名是新的。 添加它們是為了允許從value_type以外的rvalue類型移動,這些類型可以轉換為value_type P實例化為左值時,參數被復制到map ,否則它將被移動到map (const限定符允許)。

(引用的另一個insert簽名是insert-with-hint。)

我們還參考了deque的基本原理(同樣,明確引用其他容器):

將單個value_type插入(或追加,前置等)到容器中的所有成員函數都重載了一個成員函數,該函數通過rvalue引用接受該value_type,以便可以將單個value_type移動到容器中。 這不僅使重量級類型的工作更加有效,而且還允許人們將可移動但不可復制的類型插入容器中。

很明顯,這些變化主要被視為增加; 當時沒有考慮模板重載可以完全替換原始(C ++ 03) insert 這可以通過參考早期的n1771來看出 ,它為模板重載提供了一些動機,采用了不同的方法:

請注意,對於map和multimap,有兩個新的插入重載,兩者都使用非const key_type。 無法從const key_type移動,因此為了能夠將key_type移動到(多)映射中,必須使用一對。 const lvalue對和非const rvalue對都有重載,因此不會移動左值對。

 pair<iterator, bool> insert(const value_type& x); // CC pair<iterator, bool> insert(const pair<key_type,mapped_type>& x); // CC pair<iterator, bool> insert(pair<key_type,mapped_type>&& x); 

CCCopyConstructible的縮寫。)

然后看起來template重載被添加到mapmultimap而沒有意識到它們使const value_type &重載成為冗余。 您可以考慮提交缺陷報告以刪除冗余重載。

不同之處在於所使用的參考類型。 首先

std::unordered_map::insert(const value_type&)

在(C ++ 11)中使用引用(C ++ 03)現在稱為左值引用。 這需要是常量。 C ++ 11引入了rvalue引用P&& ,它們不需要是const。 為了兼顧兩者,提供了兩個插入功能。

請參閱StackOverflow上的這個優秀答案wrt rvalue C ++ 11中的參考資料,我希望這有助於回答您的問題。

T &&(雙&符號)在C ++ 11中意味着什么?

如你所說,可以使用rvalue-overload並只傳遞一個const lvalue ref,但是 - 請參閱http://msdn.microsoft.com/en-us/library/dd293668.aspx中的這篇文章

通過重載函數以獲取const左值引用或右值引用,您可以編寫區分不可修改對象(左值)和可修改臨時值(rvalues)的代碼。

-Hannes

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM