[英]overload of std::unordered_map::insert
Would you teach me why both 你能教我两者吗?
std::unordered_map::insert(const value_type&)
and 和
template<class P> std::unordered_map::insert(P&&)
exist in the standard? 存在于标准中?
I think that insert(P&&)
can serve as insert(const value_type&)
. 我认为
insert(P&&)
可以作为insert(const value_type&)
。
Both of these overloads 这两个都是重载
auto std::unordered_map::insert(const value_type&) -> ...
template<class P>
auto std::unordered_map::insert(P&&) -> ...
have their advantages and neither can fully replace the other. 有自己的优势,也不能完全取代对方。 The first one seems like a special case of the second one since
P
might be deduced to be const value_type&
. 第一个似乎是第二个的特例,因为
P
可能被推导为const value_type&
。 The nice thing about the 2nd overload is that you can avoid unnecessary copies. 关于第二次重载的好处是你可以避免不必要的副本。 For example, in this case:
例如,在这种情况下:
mymap.insert(make_pair(7,"seven"));
Here, the result of make_pair is actually a pair<int, const char*>
whereas value_type
might be pair<const int, string>
. 这里,make_pair的结果实际上是一
pair<int, const char*>
而value_type
可能是pair<const int, string>
。 So, instead of creating a temporary value_type
object and copying it into the container, we have the chance of directly creating the value_type
object into the map by converting the argument and/or moving its members. 因此,我们不是创建临时的
value_type
对象并将其复制到容器中,而是通过转换参数和/或移动其成员,直接在地图中创建value_type
对象。
On the other hand, it would be nice if this worked as well: 另一方面,如果这样做也会很好:
mymap.insert({7,"seven"});
But this list is actually not an expression! 但这个清单实际上不是表达! The compiler can't deduce P for the second overload because of that.
因此,编译器无法推断出第二次重载的P. The first overload is still viable since you can copy-initialize a
pair<const int,string>
parameter with such a list. 第一个重载仍然可行,因为您可以使用这样的列表复制初始化一
pair<const int,string>
参数。
The template universal reference overload was added in n1858 , with rationale (for map
, but the same explicitly applies to multimap
): 在n1858中添加了模板通用引用重载,具有基本原理(对于
map
,但同样明确适用于multimap
):
Two of the
insert
signatures are new.其中两个
insert
签名是新的。 They have been added to allow moving from rvalue types other thanvalue_type
, which are convertible tovalue_type
.添加它们是为了允许从
value_type
以外的rvalue类型移动,这些类型可以转换为value_type
。 WhenP
instantiates as an lvalue, the argument is copied into themap
, else it is moved into themap
(const qualifiers permitting).当
P
实例化为左值时,参数被复制到map
,否则它将被移动到map
(const限定符允许)。
(The other insert
signature referred to is insert-with-hint.) (引用的另一个
insert
签名是insert-with-hint。)
We also refer to the rationale for deque
(again, explicitly referenced for other containers): 我们还参考了
deque
的基本原理(同样,明确引用其他容器):
All member functions which insert (or append, prepend, etc.) a single value_type into the container are overloaded with a member function that accepts that value_type by rvalue reference so that single value_type's can be moved into the container.
将单个value_type插入(或追加,前置等)到容器中的所有成员函数都重载了一个成员函数,该函数通过rvalue引用接受该value_type,以便可以将单个value_type移动到容器中。 This not only makes working with heavy weight types much more efficient, it also allows one to insert movable but non-copyable types into the container.
这不仅使重量级类型的工作更加有效,而且还允许人们将可移动但不可复制的类型插入容器中。
It's apparent that the changes were considered principally as additions; 很明显,这些变化主要被视为增加; it wasn't considered at the time that the template overload could replace the original (C++03)
insert
entirely. 当时没有考虑模板重载可以完全替换原始(C ++ 03)
insert
。 This can be seen by referring to the earlier n1771 , which provides some motivation for the template overload, taking a different approach: 这可以通过参考早期的n1771来看出 ,它为模板重载提供了一些动机,采用了不同的方法:
Note below that for map and multimap that there are two new insert overloads, both taking a pair with a non-const key_type.
请注意,对于map和multimap,有两个新的插入重载,两者都使用非const key_type。 One can not move from a const key_type, and therefore to be able to move a key_type into the (multi)map, a pair must be used.
无法从const key_type移动,因此为了能够将key_type移动到(多)映射中,必须使用一对。 There are overloads for both a const lvalue pair, and a non-const rvalue pair so that lvalue pair's will not be moved from.
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
is an abbreviation for CopyConstructible
.) (
CC
是CopyConstructible
的缩写。)
It appears then that the template
overloads were added to map
and multimap
without realising that they made the const value_type &
overloads redundant. 然后看起来
template
重载被添加到map
和multimap
而没有意识到它们使const value_type &
重载成为冗余。 You might consider submitting a defect report to have the redundant overloads removed. 您可以考虑提交缺陷报告以删除冗余重载。
the difference lies in the type of reference used. 不同之处在于所使用的参考类型。 The first
首先
std::unordered_map::insert(const value_type&)
uses a Reference (C++03) now called an lvalue Reference in (C++11). 在(C ++ 11)中使用引用(C ++ 03)现在称为左值引用。 This needs to be const.
这需要是常量。 C++11 introduced rvalue References
P&&
which need not to be const. C ++ 11引入了rvalue引用
P&&
,它们不需要是const。 To allow for both, two insert functions are provided. 为了兼顾两者,提供了两个插入功能。
Please see this excellent answer on StackOverflow wrt rvalue References in C++11, I hope this helps to answer your question. 请参阅StackOverflow上的这个优秀答案wrt rvalue C ++ 11中的参考资料,我希望这有助于回答您的问题。
What does T&& (double ampersand) mean in C++11? T &&(双&符号)在C ++ 11中意味着什么?
As you said, it is possible to use the rvalue-overload and just pass a const lvalue ref, but - see this text from http://msdn.microsoft.com/en-us/library/dd293668.aspx 如你所说,可以使用rvalue-overload并只传递一个const lvalue ref,但是 - 请参阅http://msdn.microsoft.com/en-us/library/dd293668.aspx中的这篇文章
By overloading a function to take a const lvalue reference or an rvalue reference, you can write code that distinguishes between non-modifiable objects (lvalues) and modifiable temporary values (rvalues).
通过重载函数以获取const左值引用或右值引用,您可以编写区分不可修改对象(左值)和可修改临时值(rvalues)的代码。
-Hannes -Hannes
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.