std::vector<T,Allocator>::emplace
| template< class... Args > iterator emplace( const_iterator pos, Args&&... args ); |
(seit C++11) (constexpr seit C++20) |
|
Fügt ein neues Element direkt vor pos in den Container ein.
Das Element wird über std::allocator_traits::construct konstruiert, was typischerweise Placement-new verwendet, um das Element an einer vom Container bereitgestellten Stelle direkt zu konstruieren. Wenn die benötigte Stelle jedoch bereits von einem vorhandenen Element belegt ist, wird das eingefügte Element zunächst an einer anderen Stelle konstruiert und dann an die benötigte Stelle verschoben.
Die Argumente args... werden als std::forward<Args>(args)... an den Konstruktor weitergeleitet. args... dürfen direkt oder indirekt auf einen Wert im Container verweisen.
Wenn nach der Operation die neue size() größer ist als die alte capacity(), findet eine Reallokation statt, in diesem Fall werden alle Iteratoren (einschließlich des end() Iterators) und alle Referenzen auf die Elemente ungültig. Andernfalls bleiben nur die Iteratoren und Referenzen vor dem Einfügepunkt gültig.
Inhalt |
[bearbeiten] Parameter
| pos | - | Iterator, vor dem das neue Element konstruiert wird |
| args | - | Argumente, die an den Konstruktor des Elements weitergeleitet werden |
| Typanforderungen | ||
-T muss die Anforderungen von MoveAssignable, MoveInsertable und EmplaceConstructible erfüllen. | ||
[bearbeiten] Rückgabewert
Iterator, der auf das eingefügte Element zeigt.
[bearbeiten] Komplexität
Linear zur Distanz zwischen pos und end().
[bearbeiten] Ausnahmen
Wenn eine Ausnahme geworfen wird, die nicht vom Kopierkonstruktor, dem Move-Konstruktor, dem Zuweisungsoperator oder dem Move-Zuweisungsoperator von T stammt, oder wenn eine Ausnahme geworfen wird, während emplace verwendet wird, um ein einzelnes Element am Ende einzufügen, und T entweder CopyInsertable oder nicht-ausnahmenbehaftet verschiebbar konstruierbar ist, hat dies keine Auswirkungen (starke Ausnahmegarantie).
Andernfalls sind die Auswirkungen undefiniert.
Beispiel
#include <iostream> #include <string> #include <vector> struct A { std::string s; A(std::string str) : s(std::move(str)) { std::cout << " constructed\n"; } A(const A& o) : s(o.s) { std::cout << " copy constructed\n"; } A(A&& o) : s(std::move(o.s)) { std::cout << " move constructed\n"; } A& operator=(const A& other) { s = other.s; std::cout << " copy assigned\n"; return *this; } A& operator=(A&& other) { s = std::move(other.s); std::cout << " move assigned\n"; return *this; } }; int main() { std::vector<A> container; // reserve enough place so vector does not have to resize container.reserve(10); std::cout << "construct 2 times A:\n"; A two{"two"}; A three{"three"}; std::cout << "emplace:\n"; container.emplace(container.end(), "one"); std::cout << "emplace with A&:\n"; container.emplace(container.end(), two); std::cout << "emplace with A&&:\n"; container.emplace(container.end(), std::move(three)); std::cout << "content:\n"; for (const auto& obj : container) std::cout << ' ' << obj.s; std::cout << '\n'; }
Ausgabe
construct 2 times A: constructed constructed emplace: constructed emplace with A&: copy constructed emplace with A&&: move constructed content: one two three
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 2164 | C++11 | war unklar, ob die Argumente auf den Container verweisen können | wurde klargestellt |
[bearbeiten] Siehe auch
| fügt Elemente ein (public member function) | |
| (C++11) |
konstruiert ein Element direkt (in-place) am Ende (public member function) |