2013-02-16 21 views
10

kullanarak parçada aşağıdaki koda bakın. Üretilen hata, non_copyable'un kopyalanamadığını gösterir, ancak taşınmasını bekledim.std :: map <> :: olmayan copyable nesneleri ve tekdüze başlatma

Tek tip başlatmayı kullanarak oluşturulan bir std::pair eklenmesi neden başarısız oluyor, ancak std::make_pair kullanılarak oluşturulmuyor? Her ikisinin de haritaya başarıyla taşınabilecek rezonanslar üretmemesi gerekiyor mu?

cevap

17

[Bu tam bir yeniden olduğunu. Benim daha önceki cevap sorunuyla ilgisi yoktu]

map iki alakalı insert aşırı yükleme vardır.

  • insert(const value_type& value) ve

  • <template typename P> insert(P&& value).

basit liste-başlatıcı map.insert({1, non_copyable()});, tüm olası aşırı yükler dikkate alınır kullandığınızda. diğer (sihirli bir çift oluşturmak için anlamına geldiğini tahmin etmeye imkan yok) mantıklı değil çünkü Ama sadece ilki (bir const value_type& alarak), bulunur. Öğeniz devredilemediğinden, ­ yükü üzerinden ilk kez çalışmaz.

Sen zaten tarif edildiği gibi, ya make_pair ile açıkça çifti oluşturarak ikinci aşırı yük çalışması veya açıkça değer türünü adlandırarak yapabilirsiniz: Şimdi liste başlatıcı aramaya bilir

typedef std::map<int, non_copyable> map_type; 

map_type m; 
m.insert(map_type::value_type({1, non_copyable()})); 

map_type::value_type kurucular, ilgili mOVA ­ ble bir bulur, ve sonuç insert fonksiyon P&& -overload bağlanan bir rvalue çiftidir.

Burada ahlaki herhalde

(Diğer bir seçenek. Bu çok daha ayrıntılı alacağı olsa piecewise_construct ve forward_as_tuple ile emplace() kullanmaktır) bu liste-ilklendiriciler yaşayabilir aşırı – bakmak ama onlar bilmek zorunda bakılacak şey!

+1

Evet, bu benim cevap silmeden önce yazdığım temelde bu. Şüphem var: neden bir 'initializer_list <>' burada yaratıldı? std :: pair 'bir tane alan bir kurucuya sahip görünmüyor. Tekdüze başlatma sözdiziminin sadece "<>" adlı normal kurucuyu alacağını düşündüm. –

+1

Ayrıca, initializer_list <> öğelerinin hepsi aynı türde olmalı, değil mi? Her iki yoruma da – eladidan

+0

+1. Örneğimde bir 'initializer_list 'bile olmamalıydı. Daha çok, std :: pair''in yapıcısını tek tip başlatmayı kullanarak çağırmak gibi bir şey. – mfontanini

İlgili konular