Wie emplace-Objekt mit no-argument-Konstruktor in std::map?
Möchte ich emplace ein Objekt in ein std::map
dessen Konstruktor keine Argumente. Allerdings std::map::emplace
scheint es erforderlich, dass mindestens ein zusätzliches argument neben den Schlüssel. Also, wie kann ich nach vorne null Argumente an den Konstruktor?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den element-Typ der
std::map<K, V>
ist eigentlichstd::pair<K, V>
, so dass, wenn Sie emplacing in eine map, die Argumente an den Konstruktor vonstd::pair
. Das ist, warum Sie nicht bestehen können, einfach den key:std::pair<K, V>
können nicht gebaut werden, die von einem einzigen argument (es sei denn, es ist ein anderes paar des gleichen Typs.) Übergeben Sie null Argumente, aber dann wird der Schlüssel mit dem Wert initialisiert, das ist wahrscheinlich nicht das, was Sie wollen.In den meisten Fällen, bewegen Werte Billig werden (und die Tasten sind klein und kopierbar) und sollte man wirklich nur tun, so etwas wie dieses:
wo
V
ist der zugeordnete Typ. Es wird mit dem Wert initialisiert und zog in den container. (Der Zug könnte sogar sein, erstellte; ich bin mir nicht sicher.)Wenn Sie sich nicht bewegen, und Sie wirklich brauchen, die
V
gebaut worden ist-müssen Sie verwenden die stückweise Bau-Konstruktor...Diese Ursachen
std::pair
zu konstruieren, das erste element mitk
und das zweite element mit null-Argumente (Wert-Initialisierung).forward_as_tuple
stattmake_tuple
?forward_as_tuple
benötigt wird.M[k];
wird die gleiche Wirkung haben wie diepiecewise_construct
malarkey.make_tuple
arbeitete für eine nonmovable geben.forward_as-tuple
würde auch versuchen zu bewegen, was nicht möglich war, für meine Klasse (absichtlich). @Brian hat mich gerettet hier.=delete
move-ctor; copy-ctor (wenn vorhanden), den angemessenen move-ctor pre-und post-Voraussetzungen.make_tuple
arbeitet für die Argumente, um Sie zu erstellen, dannforward_as_tuple
fast immer zu.std::piecewise_construct
wirklich nach vorne zu emplace in-place. Es ist das, was cppreference sagt über diesen tag auch.Ich überprüft mitstatic_assert
dass Sie den Wert-Typ der Klasse ist noncopyable und nonmovable. Es kompiliert, wennmake_tuple
bekommt ein argument im Konstruktor oder ohne. Sie schreiben fast immer aber meine Erfahrung war, dass mein Fall anders war, also +1 für @Brian 🙂Könnten Sie explizit erstellen Sie eine
pair
und pass aufmap::emplace
oder verwenden Sie den stückweise Bau-Konstruktor vonstd::pair
.Live-demo
Ich hatte das gleiche problem, wenn ich hatte zum erstellen einer
std::map
vonstd::mutex
Objekte. Das Problem ist, dassstd::mutex
ist weder kopierbar noch verschiebbar, so dass ich brauchte, um es zu konstruieren "in place".Akzeptierte Antwort funktioniert nicht für diesen Fall (
M.emplace(k, V{});
muss V beweglich sein). Und ich wollte nicht zu verwenden, die komplizierter und weniger lesbarstd::piecewise_construct
option (siehe oben in anderen Antworten).Meine Lösung ist viel einfacher - benutzen Sie einfach
operator[]
- es schaffen wird, den Wert mit seiner Standard-Konstruktor auf und geben einen Hinweis darauf. Oder es wird nur finden und Rückgabe eine Referenz auf das bereits vorhandene Element, ohne eine neue erstellen.try_emplace
(C++17) oderemplace
, wie in anderen Antworten. Beachten Sie auch, dass diese Antwort ist sauberer visuell, aber ist etwas langsamer (nur wirklich wichtig, wenn Sie tun eine Tonne), da es (d.h.operator[]
) hat zu prüfen, um die Existenz des Objekts, so kann es wissen, ob Sie zurückkehren, was Sie finden, oder erstellen Sie ein neues Objekt zuerst da.In C++17, die Sie verwenden können
std::map::try_emplace
, verwendetstd::piecewise_construct
intern und sieht nicht sperrig. Es dauert auch eine Taste, sobald das erste argument (anstelle von Weiterleitung alles instd::pair::pair()
wieemplace
tut).Live-Beispiel.