2013-02-06 29 views
15

bana öğretebilir misin eklemek?aşırı yük :: hem</p> <pre><code>std::unordered_map::insert(const value_type&) </code></pre> <p>ve</p> <pre><code>template<class P> std::unordered_map::insert(P&&) </code></pre> <p>standardında mevcut neden

insert(P&&)'un insert(const value_type&) olarak hizmet verebileceğini düşünüyorum.

+3

Sessizlik ........ –

+0

Muhtemelen TR1'den miras. Belki de güvenli olmak istediler ve işlevleri kaldırmayıp sadece onları eklediler. Belki de TR1 kullanılan mevcut kod üzerindeki etki anında kesin değildi. –

+0

bir [programı] oluşturmak için güvenilir (http://liveworkspace.org/code/4y16As$46) 'm kaldırmak (const VALUE_TYPE &) eklemek halinde derlenmeyecektir bu 've başarısız oldu. Kimsenin düşünceleri var mı? – Yakk

cevap

7

Hem kendi avantajları var ve hiçbiri tamamen başka yerini alabilir.Birincisi , P'un const value_type& olması nedeniyle ikinci bir özel durum gibi, gibi görünüyor. 2. aşırı yük ile ilgili güzel şey, gereksiz kopyalardan kaçınmanızdır. Örneğin, bu durumda: İşte

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

, make_pair sonucu value_type oysa bir pair<int, const char*>pair<const int, string> olabilir aslında. Bu nedenle, nesnesini ve nesnesini kopyasını kabın içine kopyalamak yerine, argümanı dönüştürerek ve/veya üyelerini taşıyarak value_type nesnesini doğrudan haritaya oluşturma şansımız olur.

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

Ama bu liste aslında bir ifadesidir: Bu kadar iyi çalıştı Öte yandan

, güzel olurdu! Derleyici, bunun için ikinci aşırı yük için P'yi çıkaramaz. pair<const int,string> parametresini böyle bir listeyle kopyalayabildiğinizden, ilk aşırı yük hala geçerlidir.

+0

Çok teşekkürler! “Insert ({7,” yedi ”})' için neden eklenemediğini (const value_type &) 'nı neden tam olarak anlayamadığımdan, standardı daha fazla okudum. Tekrar teşekkürler!! –

+0

Bir [ilgili soru] gönderdim (http://stackoverflow.com/questions/14757809/overload-of-stdunordered-mapinsert-reloaded). –

2

Buradaki fark, kullanılan referans türündedir. İlk

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

hemen (C++ 11) 'de bir lvalue referans olarak adlandırılan bir başvuru (C++ 03) kullanır. Bunun const olması gerekiyor. C++ 11, const olması gerekmeyen rueue References P&&'u tanıtmıştır. Her ikisine birden izin vermek için, iki ekleme işlevi sağlanmıştır.

Lütfen bu mükemmel cevabı C++ 11'deki StackOverflow wrt rvalue Referansları kısmına bakın, umarım bu, sorunuzu yanıtlamanıza yardımcı olur.

What does T&& (double ampersand) mean in C++11?

bunu rvalue-aşırı kullanmak ve sadece const lvalue ref geçer, ama mümkündür, söylediği gibi - 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).

-Hannes bu metni görmek

+0

oops, bağlantının tekrarı için üzgünüm. Henüz cevabım olmadığında cevabımı yazmaya başladım ama kesintiye uğradım. –

+1

Sadece her iki bağlantılı yazının ilk bölümünü (hareket anlamıyla ilgili) okumak yerine, muhtemelen mükemmel yönlendirme ve referans daraltma kuralları ile ilgili ikinci bölümleri de okumalısınız. 'Insert', aktarılan argümanı kopyalayacağından veya taşıyacağından, insert'in içindeki değerlerin ve değerlerin ayırt edilmesi için bir neden yoktur, 'value_type' kurucusu sizin için bunu yapacaktır. –

4

Şablon genel referans aşırı yükü n1858, mantık ile eklenmiştir (map için, ancak aynı açık multimap için geçerlidir):

Two of the insert signatures are new. They have been added to allow moving from rvalue types other than value_type , which are convertible to value_type . When P instantiates as an lvalue, the argument is copied into the map , else it is moved into the map (const qualifiers permitting).

(diğer insert imza eklemek-ile-ipucu olduğunu anılacaktır.)

Ayrıca deque için gerekçe bakınız

(yine açıkça diğer konteynerler için başvurulan):

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. 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.

Değişikliklerin esas olarak eklemeler olarak kabul edildiğini; şablon aşırı yükünün orijinal (C++ 03) insert yerine tamamen yerleştirilebileceği düşünülmedi. Bu farklı bir yaklaşımla, şablon aşırı için bazı motivasyon sağlar önceki n1771, bakarak görülebilir: (. CCCopyConstructible kısaltmasıdır)

Note below that for map and multimap that there are two new insert overloads, both taking a pair with a non-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. 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.

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); 

Sonra anlaşılıyor template aşırı yüklemeleri, const value_type & aşırı yüklerini gereksiz yaptıklarının farkında olmadan map ve multimap'a eklenmiştir. Yedek aşırı yüklenmelerin kaldırılması için bir kusur raporu göndermeyi düşünebilirsiniz. Bu aşırı

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

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

ait

+0

Cevabınız için teşekkür ederiz. Bununla birlikte, insert ({...}) '(sellibitze'nin cevabında) formunun da bir kopya oluşsa bile yararlı olduğunu düşünüyorum. –

İlgili konular