71 votes

Y a-t-il une raison d'utiliser std :: map :: emplace () au lieu de try_emplace () en C ++ 1z?

En C++17, std::map et std::unordered_map a obtenu un nouveau membre-modèle de fonction: try_emplace(). Ce nouvel ajout, proposé dans n4279, se comporte de façon similaire à l' emplace(), mais a les avantages suivants:

  • try_emplace() ne bouge pas de rvalue arguments si l'insertion ne se fait pas. Ceci est utile lors de la manipulation de cartes dont les valeurs sont déplacer seulement les types, tels que l' std::unique_ptr.
  • try_emplace() traite de la clé et de la arguments au mapped_type séparément, ce qui le rend un peu plus intuitive que générique des mutateurs, qui sont exprimés en termes de value_type (ce qui est std::pair).

Étant donné les avantages ci-dessus, auriez-vous jamais les utiliser, emplace() de C++11 au lieu de try_emplace() de C++1z lors de l'écriture de C++1z-seul le code?

60voto

Praetorian Points 47122

try_emplace peut en effet remplacer la plupart des utilisations de l' emplace, mais si vous avez une utilisation inhabituelle de cas d'un map , avec une non-copiable et immobiliers de type de clé, try_emplace ne fonctionnera pas car il copie ou déplace la clé. Dans ce cas, vous devez utiliser emplace avec std::pair's par morceaux de la construction constructeur pour éviter les copies et se déplace.

Même si votre type de clé est copiable et/ou mobiles, par morceaux de la construction est le seul moyen d'éviter de copier ou de déplacer la construction de la clé, alors il pourrait y avoir des cas où vous préférez que plus de try_emplace.

23voto

T.C. Points 22510

try_emplace aussi ne prend pas en charge hétérogène de recherche - il ne peut pas, parce qu'il prend la clé.

Supposons que nous avons un std::map<std::string, int, std::less<>> counts; et std::string_view sv. Je veux faire l'équivalent d' ++counts[std::string(sv)];, mais je ne veux pas créer un temporaire std::string, ce qui est juste gaspillage, surtout si la chaîne est déjà présent dans la carte. try_emplace ne peut pas vous aider là-bas. Au lieu de cela, vous feriez quelque chose comme

if(auto lb = counts.lower_bound(sv); lb != counts.end() && lb->first == sv) {
    ++lb->second;
}
else {
    counts.emplace_hint(lb, sv, 1);
}

6voto

Hariom Singh Points 2002

Je préfère toujours try_emplace sur emplace. Une différence essentielle est que try_emplace ne va pas construire l'objet associé à la clé,si la clé existe déjà.Cela permettra de booster les performances dans le cas des objets de ce type sont coûteux à créer

Par exemple, le code ci-dessous (Exemple de https://github.com/PacktPublishing/Cpp17-STL-Cookbook/blob/master/Chapter02/efficient_insert_or_reassign_to_map.cpp)

#include <iostream>
#include <functional>
#include <list>
#include <map>

using namespace std;

struct billionaire {
    string name;
    double dollars;
    string country;
};

int main()
{
    list<billionaire> billionaires {
        {"Bill Gates", 86.0, "USA"},
        {"Warren Buffet", 75.6, "USA"},
        {"Jeff Bezos", 72.8, "USA"},
        {"Amancio Ortega", 71.3, "Spain"},
        {"Mark Zuckerberg", 56.0, "USA"},
        {"Carlos Slim", 54.5, "Mexico"},
        // ...
        {"Bernard Arnault", 41.5, "France"},
        // ...
        {"Liliane Bettencourt", 39.5, "France"},
        // ...
        {"Wang Jianlin", 31.3, "China"},
        {"Li Ka-shing", 31.2, "Hong Kong"}
        // ...
    };

    map<string, pair<const billionaire, size_t>> m;

    for (const auto &b : billionaires) {
        auto [iterator, success] = m.try_emplace(b.country, b, 1);

        if (!success) {
            iterator->second.second += 1;
        }
    }


    for (const auto & [key, value] : m) {
        const auto &[b, count] = value;

        cout << b.country << " : " << count << " billionaires. Richest is "
        << b.name << " with " << b.dollars << " B$\n";
    }
}

Pour le code ci-dessus

m.try_emplace(b.country, b, 1);

si il y a échec de l'insertion, les paires ne sera pas se construit qui ajoute à la performance

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X