2012-07-20 21 views
17

varsayalım Aşağıdaki kod var:Taşı :: push_back

#include <vector> 
struct A { 
    int a; 
    int x; 
}; 
int main() { 
    using namespace std; 
    A a1; 
    A a2; 
    vector<A> va; 
    va.push_back(a1); 
    va.push_back(move(a2)); 
} 

Ben std :: vektör elemanları std :: listeye aksine bitişik olarak saklandığı farkındayım. Yukarıdaki kodda a2 taşınır ama a2 vektörü va vektörüne gerçekten kopyalanmıyor mu? va.push_back(a2); ve arasındaki fark nedir? Eğer va.push_back(move(a2)) versiyonu vector<T>::push_back(T&&) adı verilecek kullandığınızda va.push_back(a2) sürümü vector<T>::push_back(const T&) kullanmak

+2

, 'std ::' move'ing a2' yapar tam * hiçbir şey *, bir düz tip (yani, harici veri yok) ve irade hala kopya beri. – Xeo

+0

@cdhowie Teşekkürler. düzeltildi. – ggg

+0

Okumak için bir giriş yapmak için [Birisi lütfen bana semantik anlamını açıklayabilir misiniz?] (Http://stackoverflow.com/questions/3106110/) okumak isteyebilirsiniz. – fredoverflow

cevap

26

, hiçbir etkili bir fark yoktur. Hareket ettirilebilir nesneler kullanırken fark edilir bir performans farkı göreceksiniz ve kopyalamak için çok çaba harcarsınız. Bu durumda, push_back(x) kullanarak, nesnenin bir kopyasını oluşturur, push_back(move(x))push_back() söyler, x içeriğini çalabilir ve x, kullanılamaz ve tanımlanmamış bir durumda bırakabilir. Eğer listelerin bir vektör (std::vector<std::list<int> >) vardı ve 100.000 öğe içeren bir liste itmek isterse

düşünün. move() olmadan, tüm liste yapısı ve tüm 100.000 öğe kopyalanacaktır. move() ile, bazı işaretçiler ve diğer küçük veri parçaları karıştırılır ve bu konuyla ilgilidir. Bu çok daha hızlı olacak ve daha az genel bellek tüketimi gerektirecektir.

+1

Neden? hareket c-tor otomatik olarak üretilecek, öyle değil mi? – ForEveR

+6

@ForEveR Kişinin otomatik olarak oluşturulup oluşturulmadığı farketmez, çünkü taşınabilen 'A' yapısında hiçbir tahsis yoktur. Yalnızca iki 'ın' vardır ve taşıma yapıcısı kopya oluşturucunun yapacağı aynı şeyi yapar: kaynak nesnede bulunan ints değerlerini yeni nesneye atayın. Bu senaryoda hareket senaryosunda optimizasyon mümkün değildir, çünkü alabildiğine en uygun halidir. – cdhowie

+0

@cdhowie Bir hareket sırasında her zaman bir şey kopyalanacaktır? – ggg

14

performansı için hiçbir fark yoktur

Ama senin durumunda

beri ..., adı verilecek Bir sendikasız sınıf X için örtülü olarak tanımlanmış kopyala/taşı yapıcı, tabanlarının ve üyelerinin üye olarak bir kopyasını/hareketini gerçekleştirir.

Paragraf 12.8 n3337 taslak. Eğer derleyici tarafından sağlanan kopya kurucular kullandığınız beri durumda

0

diğer cevaplar yanına gitmiş olmayan bir şeyi not etmek istiyorum; (Eğer trivially copyable nesneleri varken) hareket kurucu ihtiyacı sıfıra \ etkin bir yazıyorsun \ iki nesneyi kopyalama taşındı nesne, set çünkü ?.push_back(move(?)), senin durumunda ?.push_back(?) daha yavaş olacak olmasıdır. Senin durumunda

+0

Taşınan nesneye bir şey yapması için bir hareket yapıcısı gerekli değildir. Sıfırlanması gereken işaretçiler taşınmazsa, hiçbir şeyi sıfırlamanıza gerek yoktur. (Derleyici tarafından oluşturulan hareket yapıcılar, kaynak nesneyi batıramazlar.) – cdhowie

İlgili konular