Çubuğu bazı izleme değişken 'x' kopyalama boş setini çağırır ve bu ana değiştirin:}
int main(int argc, char *argv[]) {
printf("map\n");
std::map<int, vec> z;
printf("vec\n");
vec x;
printf("pair\n");
std::pair<int,vec> y(1,x);
printf("insert\n");
z.insert(y);
printf("inserted 1\n");
y.first = 2;
printf("insert\n");
z.insert(y);
printf("inserted 2\n");
Çıktı:
$ make mapinsert CXXFLAGS=-O3 -B && ./mapinsert
g++ -O3 mapinsert.cpp -o mapinsert
map
vec
pair
getMem n 0 ptr 0x6b0258
insert
getMem n 0 ptr 0x6b0268
getMem n 32 ptr 0x6b0278
getMem n 0 ptr 0x6b02a0
FreeMemory ptr 0x6b0268
inserted 1
insert
getMem n 0 ptr 0x6b0268
getMem n 32 ptr 0x6b02b0
getMem n 0 ptr 0x6b02d8
FreeMemory ptr 0x6b0268
inserted 2
FreeMemory ptr 0x6b0258
FreeMemory ptr 0x6b02d8
FreeMemory ptr 0x6b02b0
FreeMemory ptr 0x6b02a0
FreeMemory ptr 0x6b0278
senin 3 0 büyüklüğünde allo Yani katyonlar:
- Biri boş vektörü çifti içine kopyalamaktır.
- Biri, boş vektörün bir kopyasını haritada saklamaktır.
Bu iki açıkça gereklidir. Ne hakkında emin değilim şudur:
- Bir
insert
çağrısına yerde vektör kopyalamak ve bu da eklemek için çağrıda arındırılır.
(dahili olarak aramalar falan) değeriyle yerine referans olarak kendi parametre alıyor, ya da yeni harita düğümünü ayırır önce insert
açıkça bir otomatik değişken içine biraz zaman bir kopyasını alıyor insert
sanki. Bir hata ayıklayıcısını yakmak şu an benim için bir çaba, onu başka birine bırakacağım.
Düzenleme: gizem çözüldü. insert
, std::pair<int, vec>
değil, std::pair<const int, vec>
alır. Boş bir vektörün fazladan kopyası, oluşturduğunuz çiftin bir (noter) geçici hale dönüştürülmesi gerektiğinden, bu geçici referansa insert
aktarılır. std :: pair, hemen hemen her şeyden kurtulmanızı sağlayan bir kurgu şablonuna sahiptir./4 20.2.2:
template<class U, class V> pair(const pair<U,V> &p);
Etkileri: gerekli olarak örtülü dönüşüm yapmak, argüman karşılık gelen üyelerinden üye başlatır.getMem
çağırmaz
Ben de uygulanmasında görüyoruz, vec x;
fakat vec x(0);
yapar. Yani aslında:
z[1] = vec();
az şifre mi ve (yerine operator=
çağırır rağmen) ekstra kopyasını fırsatı reddeder. En azından benim için hala 2 0 boyutlu tahsisat yapıyor.
C++ standardı, insert
numaralı aramayı içeren belirli bir ifadenin sonucunu döndürmek için operator[]
öğesini tanımlar. Bu, operator[]
'un "sanki" make_pair
ve insert
etkilerinin (yani, standardın operator[]
için ne olması gerektiğini belirten kadar iyi olduğu) veya yalnızca döndürülen değerin mi olduğu anlamına geldiğinden emin değilim. Belirtilen ifade ile aynı değer verir. Eğer ikincisi o zaman belki de bir uygulama bunu tek bir 0 boyutlu tahsis ile yapabilirdi. Ancak kesinlikle map
, eşlenmiş türden bir çift oluşturmadan bir giriş oluşturmanın garantili bir yolu yoktur, bu nedenle 2 ayırma beklenmelidir. Veya daha doğrusu, istenen eşlenen değerin 2 kopyası: 0 büyüklüğünde bir vektörün kopyalanması 0 büyüklüğünde bir tahsisatın uygulamaya bağlı olması gerçeğidir. Eğer değer kopyalamak için gerçekten pahalı ama varsayılan-yapısı için (elementlerin dolu bir kap gibi) gerçekten ucuz bir dava olsaydı
yani, sonra aşağıdaki yararlı olabilir:
std::map<int, vec> z;
vec x(1000);
z[1] = x;
// i.e. (*(z.insert(std::pair<const int, vec>(1,vec())).first)).second = x;
ise, boyutu 4000 ve boyut 0 ile 2 arasında 2 tahsisleri yapar:
std::map<int, vec> z;
vec x(1000);
z.insert(std::pair<const int, vec>(2, x));
büyüklüğü 4000 3 yapar ve boyut 0 hiçbirinin Sonunda boyutu birinci kod ilave ayırma daha ucuz olduğu kadar büyük ikinci kodda fazladan kopyalama.
C++ 0x'deki hareket-yapıcıların bu konuda yardımcı olması muhtemel, emin değilim.
Tüm çabanız için teşekkürler. Bu cevabı bir * verebilseydim, yapardım. –
Bu, vektörler gibi şeyleri bir haritaya yerleştirirken en iyi uygulamanın neden yazılmamış vektör yapmak olduğunu gösteren iyi bir örnektir vec_t; typedef map map_t; vec_t dummy; map_t myvals; vec_t tvals (100000,3);/* vali */myvals.insert (map_t :: value_type (1, kukla)) first-> second.swap (tvals); Bu, sadece bir vec_t'nin harita düğümünü yapmak için kopyalanmasını ve ardından düğüm oluşturulduğunda (veya zaten var ise) değerlerin taşınmasını sağlar. Eşdeğer C++ 0x yolu myvals.insert (map_t :: value_type (1, std :: move (tvals))); –