Namensräume
Varianten
Aktionen

std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::try_emplace

Von cppreference.com
 
 
 
 
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 vorhanden ist, der zu k äquivalent ist, wird nichts unternommen. Andernfalls wird ein neues Element in den Container eingefügt, mit dem Schlüssel k und dem Wert, der mit args konstruiert wurde. In diesem Fall

1) Verhält sich wie emplace, außer dass das Element konstruiert wird als
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 konstruiert wird als
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 konstruiert wird als
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 konstruiert wird als
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 konstruiert wird als
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 konstruiert wird als
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 unordered_map-weise aus dem entsprechenden Ausdruck konstruierbar ist (EmplaceConstructible), ist das Verhalten undefiniert.
3) Diese Überladung nimmt nur an der Auflösung von Überladungen teil, wenn alle folgenden Bedingungen erfüllt sind
Wenn hash_function()(u.first) != hash_function()(k) || contains(u.first) true ist, ist das Verhalten undefiniert, wobei u das neu einzufügende Element ist.
6) Diese Überladung nimmt nur an der Overload Resolution teil, wenn Hash::is_transparent und KeyEqual::is_transparent beide gültig sind und jeweils einen Typ bezeichnen.
Wenn hash_function()(u.first) != hash_function()(k) || contains(u.first) true ist, ist das Verhalten undefiniert, wobei u das neu einzufügende Element ist.

Wenn nach der Operation die neue Anzahl der Elemente größer ist als max_load_factor() * bucket_count(), findet ein Rehashing statt.
Wenn Rehashing stattfindet (aufgrund der Einfügung), werden alle Iteratoren ungültig. Andernfalls (kein Rehashing) werden Iteratoren nicht 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
Im Durchschnitt amortisiert konstant, im schlimmsten Fall linear zur Größe des Containers.
4-6) Wie für emplace_hint
Im Durchschnitt amortisiert konstant, im schlimmsten Fall linear zur Größe des Containers.

[bearbeiten] Anmerkungen

Im Gegensatz zu insert oder emplace verschieben diese Funktionen keine R-Wert-Argumente, wenn die Einfügung nicht stattfindet. Dies erleichtert die Manipulation von Maps, deren Werte nur verschiebbar sind (move-only types), wie z.B. std::unordered_map<std::string, std::unique_ptr<foo>>. Darüber hinaus behandelt try_emplace den Schlüssel und die Argumente für den mapped_type separat, im Gegensatz zu emplace, das Argumente zur Konstruktion 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_unordered_map_try_emplace 201411L (C++17) std::unordered_map::try_emplace,
std::unordered_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 <unordered_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::unordered_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);
}

Mögliche Ausgabe

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

[bearbeiten] Siehe auch

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]