Die Effizienz von C++11 push_back() mit std::move versus emplace_back() für die bereits errichteten Objekte
In C++11 emplace_back()
ist in der Regel bevorzugt (im Sinne von Effizienz) push_back()
da es ermöglicht, in-place-Konstruktion, aber ist dies immer noch der Fall, wenn mit push_back(std::move())
mit einem bereits gebauten Objekt?
Beispielsweise ist emplace_back()
noch bevorzugt in Fällen wie den folgenden?
std::string mystring("hello world");
std::vector<std::string> myvector;
myvector.emplace_back(mystring);
myvector.push_back(std::move(mystring));
//(of course assuming we don't care about using the value of mystring after)
Darüber hinaus gibt es einen nutzen in dem obigen Beispiel statt so:
myvector.emplace_back(std::move(mystring));
oder ist der Schritt hier völlig überflüssig, oder hat das keine Auswirkungen?
InformationsquelleAutor der Frage Riot | 2014-11-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lassen Sie uns sehen, was die verschiedenen Anrufe, die Sie tun:
emplace_back(mystring)
: Dies ist ein in-place-Bau das neue element, mit welchem argument Sie zur Verfügung gestellt. Da Sie eine lvalue, dass in-place-Konstruktion in der Tat ist eine Kopie-Konstruktion, also das ist das gleiche wie der Aufrufpush_back(mystring)
push_back(std::move(mystring))
: Dies fordert die move-insertion, die im Fall von std::string ist ein in-place-Bewegung-Bau.emplace_back(std::move(mystring))
: Das ist wieder ein in-place-Konstruktion mit den Argumenten, die Sie zur Verfügung gestellt. Da dieses argument ist ein rvalue, ruft es die move-Konstruktorstd::string
d.h. es ist eine in-place-move-Konstruktion wie in 2.In anderen Worten, wenn der Aufruf mit einem argument vom Typ T, sei es ein rvalue oder lvalue,
emplace_back
undpush_back
gleichwertig sind.Jedoch für jedes andere argument(s)
emplace_back
gewinnt das Rennen, zum Beispiel mit einemchar const*
imvector<string>
:emplace_back("foo")
Anrufestring::string(char const*)
für in-place-Konstruktion.push_back("foo")
ersten rufenstring::string(char const*)
für die implizite Konvertierung erforderlich, entsprechend der Funktion, die Unterschrift, und dann " move-insertion wie Fall 2. oben. Es ist daher äquivalent zupush_back(string("foo"))
InformationsquelleAutor der Antwort Arne Mertz
Den emplace_back bekommt eine Liste von rvalue-Referenzen und versucht, zu erstellen eine container-element direkt im Ort. Sie können rufen Sie emplace_back mit allen Typen, die das container-element-Konstruktoren unterstützt.
Wenn der Anruf emplace_back für Parameter, die nicht rvalue-Referenzen, die es 'zurück' zu normalen Referenzen, und zumindest der kopierkonstruktor tritt aufgerufen, wenn die parameter und die container-Elemente sind vom gleichen Typ.
In Ihrem Fall 'myvector.emplace_back(mystring)' eine Kopie der Zeichenfolge, da der compiler nicht wissen konnte, dass der parameter myvector ist beweglich. So legen Sie die std::move, was gibt Ihnen den gewünschten nutzen.
Die push_back sollte die Arbeit als auch für emplace_back bereits konstruierte Elemente.
InformationsquelleAutor der Antwort Tunichtgut