std::map::try_emplace în C++

try_emplace adaugă doar dacă cheia lipsește; insert_or_assign adaugă sau înlocuiește și spune ce a făcut.

Sintaxă
template<class... Args>
std::pair<iterator, bool> try_emplace(const Cheie& cheie, Args&&... argumente);

template<class M>
std::pair<iterator, bool> insert_or_assign(const Cheie& cheie, M&& valoare);

Ce face std::map::try_emplace

try_emplace(cheie, argumente...) construiește valoarea din argumente doar dacă cheia nu există. Spre deosebire de emplace, dacă cheia există, argumentele nu sunt atinse deloc (de exemplu, un std::string mutat nu se pierde). Cheia și valoarea se dau separat, ceea ce face codul mai clar.

insert_or_assign(cheie, valoare) face ce face m[cheie] = valoare, dar: nu cere ca valoarea să aibă constructor implicit și returnează .second == true dacă a adăugat o cheie nouă, false dacă a înlocuit una existentă.

Parametri

Parametru Descriere
cheie Cheia căutată.
argumente / valoare Pentru try_emplace: argumentele constructorului valorii. Pentru insert_or_assign: noua valoare.

Ce returnează

std::pair<iterator, bool>: iteratorul la element și true dacă s-a adăugat o cheie nouă.

Exemple

Exemplul 1: try_emplace: prima valoare câștigă

#include <map>
#include <print>
#include <string>

int main() {
    std::map<std::string, std::string> rezervari;
    rezervari.try_emplace("masa 1", "Ana");
    auto [it, ok] = rezervari.try_emplace("masa 1", "Ion");
    std::println("Rezervare nouă? {}. Masa 1 este a lui {}", ok, it->second);

    rezervari.try_emplace("masa 2", 3, '-');   // std::string(3, '-')
    std::println("{}", rezervari);
}

Rezultat

Rezervare nouă? false. Masa 1 este a lui Ana
{"masa 1": "Ana", "masa 2": "---"}

Exemplul 2: insert_or_assign: adaugă sau actualizează

#include <map>
#include <print>
#include <string>

int main() {
    std::map<std::string, double> curs;
    for (auto [moneda, valoare] : {std::pair{"EUR", 4.97}, std::pair{"USD", 4.55}, std::pair{"EUR", 4.98}}) {
        bool nou = curs.insert_or_assign(moneda, valoare).second;
        std::println("{:<11} {} = {}", nou ? "adăugat:" : "actualizat:", moneda, valoare);
    }
    std::println("{}", curs);
}

Rezultat

adăugat:    EUR = 4.97
adăugat:    USD = 4.55
actualizat: EUR = 4.98
{"EUR": 4.98, "USD": 4.55}

Greșeli frecvente

  • Folosești emplace(cheie, std::move(text)) și te miri că text s-a golit, deși cheia exista. emplace poate construi perechea înainte să afle că cheia există; try_emplace garantează că nu se atinge nimic.

Comenzi înrudite

  • std::map::insert: Adaugă o pereche cheie-valoare doar dacă cheia nu există; spune prin rezultat dacă a adăugat-o.
  • std::map: Dicționar ordonat: asociază fiecărei chei unice o valoare și păstrează cheile sortate.
  • std::vector::emplace_back: Construiește un element nou direct la sfârșitul vectorului, din argumentele constructorului.