Da C++ 11, Insertion assoziativen Container erfordert entweder copy-costructible lvalues oder move-einführbaren veränderbare rvalues. Also, es gibt kein Problem beim Aufruf insert()
zusammen mit make_pair()
, wie Sie tun: Letzteres erstellt eine pair<const char[],unique_ptr>
, die verwendet wird, um einen value_type
rvalue zu initialisieren.
Das Problem mit der Klammer Initialisierung ist, dass (bis C++ 17) die value_type const & Überlastung bevorzugt wird (weil es & & Überlastung keine richtige value_type ist), also eine Kopie angefordert wird und ein Fehler ausgelöst wird.
In der Tat, beachten Sie, dass beide Formulare in gcc Stamm und 5 (mit libC++) im C++ 17-Modus kompilieren.
Genauer gesagt, von C++ 11 auf, die entsprechenden Einsatz semantischen Anforderungen lesen
[unord.req] If t is a non-const rvalue expression, value_type shall be MoveInsertable into X; otherwise, value_type shall be CopyInsertable into X.
die tatsächlichen Mitglieder Spezifikation ist, wo die Dinge unterscheiden; bis C 17 ++, haben wir:
pair<iterator, bool> insert(const value_type& obj);
template <class P> pair<iterator, bool> insert(P&& obj);
...
wo die allgemeine Überlastung SFINAE zu std::is_constructible<value_type, P&&>::value
eingeschränkt. Bei Verwendung einer braced-init-Liste wird die Überladung const & hier ausgewählt (Anmerkung: Es gibt auch eine initializer_list-Überladung, aber dies gilt nicht für den OP-Fall).
Stattdessen in C++ 17 haben wir auch
pair<iterator, bool> insert(value_type&& obj);
Sie sind C++ 14 verwenden, denn bevor es keine 'std :: war make_unique'. – Rakete1111
afaik fügt Kopien ein (unique_ptr ist nicht kopierbar), benutze emplace – Sopel