2012-08-09 15 views
6

I push_back tymczasowy obiekt do vector jak ta,vector.push_back RValue i kopia elizja

vector<A> vec; 
vec.push_back(A("abc")); 

będzie kompilator stosuje copy-elizja na budowę tymczasowego A("abc") bezpośrednio do vector, tak że A ' s ctor ctor nie zostanie wyzwolony podczas przesuwania tymczasowego obiektu do vec.

+0

Nie sądzę tak dlatego, że 'vector' (podzielników STL faktycznie) używa kwalifikacyjny' new'. –

+0

@Seth Carnegie - jak to się ma do umieszczenia "nowego"? załóżmy, że masz wystarczająco dużo wolnego miejsca w wektorze, wtedy kompilator może po prostu skonstruować instancję 'A' na miejscu. –

+0

@Nya ponieważ kompilator prawdopodobnie nie będzie zorientować się, gdzie zostanie on utworzony (nie to, że nie można, ale to, że nie będzie, bo twórcy kompilatora nie pisać, że optymalizacja). –

Odpowiedz

5

Jeśli masz kompilatora, który obsługuje referencje rvalue, zostanie on przeniesiony do wektora, który jest czasami dość tani.

Alternatywą to bezpośrednio skonstruowania obiektu w wektorze, co może być wykonane z vec.emplace_back("abc");. To wywołuje tylko jeden konstruktor.

Oba są C++ 11 funkcji. Kopiowanie elizji nie jest tutaj dozwolone, więc bez tych funkcji kopia nadal będzie wykonana.

Jednakże, jeśli konstruktor kopiowania nie ma możliwych do zaobserwowania efektów ubocznych (które i tak nie powinno mieć), inteligentny kompilator może nadal wykonywać tę optymalizację, ponieważ reguła "jak to możliwe" pozwala na dowolną optymalizację, która skutkuje to samo obserwowalne zachowanie. Nie wiem jednak, czy jakikolwiek obecny kompilator to robi. Jeśli nie, wątpię, by ktokolwiek dołożył starań, aby dodać taką optymalizację, ponieważ referencje rvalue położyły kres tej potrzebie.

+0

Nie używam teraz C++ 11. – Alcott

+0

@Alcott, najprawdopodobniej zostanie wykonana kopia. –

+0

@ R.MartinhoFernandes lub operator przypisania zostanie wywołany; Widziałem oba przypadki, i sądzę, że zależy to od tego, czy zdefiniowano konstruktora kopii, czy też zdefiniowano operatora przypisania dla klasy (może oba?). Kolejny powód, dla którego "Effective STL" jest niezbędny dla wszystkich programistów C++; Meyers mówi o używaniu klas z kontenerami STL i porusza się, dlaczego/jak implementować klasy, które będą w nich przechowywane. – Will

1

W ogólnym przypadku nie można tego zrobić, może to być zrobione tutaj, ponieważ vector jest szablonem, a kod może być wstawiony, dając więcej informacji optymalizatorowi, aby wykonać to zadanie i odciążając niektóre z wymagań funkcji połączenia.

W ogólnym przypadku, kopia dzieła elizja poprzez umieszczenie dwóch obiektów w tym samym miejscu w pamięci i posiadające tylko dwie nazwy odnoszą się do pojedynczego obiektu. Problem w tym przypadku polegałby na tym, że jeden z argumentów musi znajdować się wewnątrz wektora (dynamicznie przydzielany, w określonej pozycji), a drugi jest argumentem funkcji, która może być związana konwencją wywołującą do określonej pozycji w stosie. W takim przypadku kompilator nie będzie mógł zoptymalizować kopii.