Namensräume
Varianten
Aktionen

std::map<Key,T,Compare,Allocator>::try_emplace

Von cppreference.com
< cpp‎ | container‎ | map
 
 
 
 
template< class... Args >
std::pair<iterator, bool> try_emplace( const Key& k, Args&&... args );
(1) (seit C++17)
template< class... Args >
std::pair<iterator, bool> try_emplace( Key&& k, Args&&... args );
(2) (seit C++17)
template< class K, class... Args >
std::pair<iterator, bool> try_emplace( K&& k, Args&&... args );
(3) (seit C++26)
template< class... Args >
iterator try_emplace( const_iterator hint, const Key& k, Args&&... args );
(4) (seit C++17)
template< class... Args >
iterator try_emplace( const_iterator hint, Key&& k, Args&&... args );
(5) (seit C++17)
template< class K, class... Args >
iterator try_emplace( const_iterator hint, K&& k, Args&&... args );
(6) (seit C++26)

Wenn ein Schlüssel existiert, der äquivalent zu k ist, wird nichts getan. Andernfalls wird ein neues Element in den Container eingefügt mit dem Schlüssel k und dem Wert, konstruiert mit args. In diesem Fall

1) Verhält sich wie emplace, außer dass das Element als konstruiert wird
value_type(std::piecewise_construct,

           std::forward_as_tuple(k),

           std::forward_as_tuple(std::forward<Args>(args)...))
2) Verhält sich wie emplace, außer dass das Element als konstruiert wird
value_type(std::piecewise_construct,

           std::forward_as_tuple(std::move(k)),

           std::forward_as_tuple(std::forward<Args>(args)...))
3) Verhält sich wie emplace, außer dass das Element als konstruiert wird
value_type(std::piecewise_construct,

           std::forward_as_tuple(std::forward<K>(k)),

           std::forward_as_tuple(std::forward<Args>(args)...))
4) Verhält sich wie emplace_hint, außer dass das Element als konstruiert wird
value_type(std::piecewise_construct,

           std::forward_as_tuple(k),

           std::forward_as_tuple(std::forward<Args>(args)...))
5) Verhält sich wie emplace_hint, außer dass das Element als konstruiert wird
value_type(std::piecewise_construct,

           std::forward_as_tuple(std::move(k)),

           std::forward_as_tuple(std::forward<Args>(args)...))
6) Verhält sich wie emplace_hint, außer dass das Element als konstruiert wird
value_type(std::piecewise_construct,

           std::forward_as_tuple(std::forward<K>(k)),

           std::forward_as_tuple(std::forward<Args>(args)...))
1-6) Wenn value_type nicht aus dem entsprechenden Ausdruck in map EmplaceConstructible ist, ist das Verhalten undefiniert.
3) Diese Überladung nimmt nur an der Auflösung von Überladungen teil, wenn alle folgenden Bedingungen erfüllt sind
Wenn equal_range(u.first) == equal_range(k) false ist, ist das Verhalten undefiniert, wobei u das einzufügende neue Element ist.
6) Diese Überladung nimmt nur an der Auflösung von Überladungen teil, wenn der qualifizierte Bezeichner Compare::is_transparent gültig ist und einen Typ bezeichnet.
Wenn equal_range(u.first) == equal_range(k) false ist, ist das Verhalten undefiniert, wobei u das einzufügende neue Element ist.

Keine Iteratoren oder Referenzen werden ungültig.

Inhalt

[bearbeiten] Parameter

k - der Schlüssel, der sowohl zur Suche als auch zum Einfügen verwendet wird, wenn er nicht gefunden wird
hint - Iterator zu der Position, vor der das neue Element eingefügt wird
args - Argumente, die an den Konstruktor des Elements weitergeleitet werden

[bearbeiten] Rückgabewert

1-3) Wie für emplace
Ein Paar, das aus einem Iterator zu dem eingefügten Element (oder zu dem Element, das die Einfügung verhindert hat) und einem bool-Wert besteht, der genau dann true ist, wenn die Einfügung stattgefunden hat.
4-6) Wie für emplace_hint
Ein Iterator zu dem eingefügten Element oder zu dem Element, das die Einfügung verhindert hat.

[bearbeiten] Komplexität

1-3) Wie für emplace
Logarithmisch zur Größe des Containers.
4-6) Wie für emplace_hint
Logarithmisch zur Größe des Containers im Allgemeinen, aber amortisiert konstant, wenn das neue Element direkt vor hint eingefügt wird.

[bearbeiten] Hinweise

Im Gegensatz zu insert oder emplace verschieben diese Funktionen keine Rvalue-Argumente, wenn die Einfügung nicht stattfindet. Dies erleichtert die Handhabung von Maps, deren Werte verschiebbare Typen sind, wie z. B. std::map<std::string, std::unique_ptr<foo>>. Darüber hinaus behandelt try_emplace den Schlüssel und die Argumente für den mapped_type getrennt, im Gegensatz zu emplace, das Argumente zum Konstruieren eines value_type (d. h. eines std::pair) benötigt.

Die Überladungen (3,6) können aufgerufen werden, ohne ein Objekt vom Typ Key zu konstruieren.

Feature-Test-Makro Wert Std Feature
__cpp_lib_map_try_emplace 201411L (C++17) std::map::try_emplace, std::map::insert_or_assign
__cpp_lib_associative_heterogeneous_insertion 202311L (C++26) Heterogene Überladungen für die verbleibenden Memberfunktionen in geordneten und ungeordneten assoziativen Containern. Überladungen (3) und (6).

[bearbeiten] Beispiel

#include <iostream>
#include <string>
#include <map>
#include <utility>
 
void print_node(const auto& node)
{
    std::cout << '[' << node.first << "] = " << node.second << '\n';
}
 
void print_result(auto const& pair)
{
    std::cout << (pair.second ? "inserted: " : "ignored:  ");
    print_node(*pair.first);
}
 
int main()
{
    using namespace std::literals;
    std::map<std::string, std::string> m;
 
    print_result(m.try_emplace("a", "a"s));
    print_result(m.try_emplace("b", "abcd"));
    print_result(m.try_emplace("c", 10, 'c'));
    print_result(m.try_emplace("c", "Won't be inserted"));
 
    for (const auto& p : m)
        print_node(p);
}

Ausgabe

inserted: [a] = a
inserted: [b] = abcd
inserted: [c] = cccccccccc
ignored:  [c] = cccccccccc
[a] = a
[b] = abcd
[c] = cccccccccc

[bearbeiten] Siehe auch

(C++11)
konstruiert Elemente direkt (in-place)
(public member function) [edit]
konstruiert Elemente "in place" unter Verwendung eines Hinweises
(public member function) [edit]
fügt Elemente ein oder Knoten(seit C++17)
(public member function) [edit]