[英]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);
( CC
是CopyConstructible
的縮寫。)
然后看起來template
重載被添加到map
和multimap
而沒有意識到它們使const value_type &
重載成為冗余。 您可以考慮提交缺陷報告以刪除冗余重載。
不同之處在於所使用的參考類型。 首先
std::unordered_map::insert(const value_type&)
在(C ++ 11)中使用引用(C ++ 03)現在稱為左值引用。 這需要是常量。 C ++ 11引入了rvalue引用P&&
,它們不需要是const。 為了兼顧兩者,提供了兩個插入功能。
請參閱StackOverflow上的這個優秀答案wrt rvalue 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.