Namespaces
Variants

std::unordered_set<Key,Hash,KeyEqual,Allocator>:: emplace_hint

From cppreference.net

template < class ... Args >
iterator emplace_hint ( const_iterator hint, Args && ... args ) ;
(depuis C++11)
(constexpr depuis C++26)

Insère un nouvel élément dans le conteneur, en utilisant hint comme suggestion pour l'emplacement où l'élément devrait être placé.

Les constructeurs de la clé et de la valeur mappée sont appelés avec exactement les mêmes arguments que ceux fournis à la fonction, transmis avec std:: forward < Args > ( args ) ... .

Si après l'opération le nouveau nombre d'éléments dépasse l'ancien max_load_factor() * bucket_count() un rehashing a lieu.
Si un rehashing se produit (en raison de l'insertion), tous les itérateurs sont invalidés. Sinon (aucun rehashing), les itérateurs ne sont pas invalidés.

Table des matières

Paramètres

hint - itérateur, utilisé comme suggestion pour l'emplacement d'insertion du nouvel élément
args - arguments à transmettre au constructeur de l'élément

Valeur de retour

Un itérateur vers l'élément inséré, ou vers l'élément qui a empêché l'insertion.

Exceptions

Si une exception est levée pour quelque raison que ce soit, cette fonction n'a aucun effet ( strong exception safety guarantee ).

Complexité

Amorti constant en moyenne, pire cas linéaire dans la taille du conteneur.

Exemple

#include <chrono>
#include <cstddef>
#include <functional>
#include <iomanip>
#include <iostream>
#include <unordered_set>
const int n_operations = 1005000;
std::size_t set_emplace()
{
    std::unordered_set<int> set;
    for (int i = 0; i < n_operations; ++i)
        set.emplace(i);
    return set.size();
}
std::size_t set_emplace_hint()
{
    std::unordered_set<int> set;
    auto it = set.begin();
    for (int i = 0; i < n_operations; ++i)
    {
        set.emplace_hint(it, i);
        it = set.end();
    }
    return set.size();
}
std::size_t set_emplace_hint_wrong()
{
    std::unordered_set<int> set;
    auto it = set.begin();
    for (int i = n_operations; i > 0; --i)
    {
        set.emplace_hint(it, i);
        it = set.end();
    }
    return set.size();
}
std::size_t set_emplace_hint_corrected()
{
    std::unordered_set<int> set;
    auto it = set.begin();
    for (int i = n_operations; i > 0; --i)
    {
        set.emplace_hint(it, i);
        it = set.begin();
    }
    return set.size();
}
std::size_t set_emplace_hint_closest()
{
    std::unordered_set<int> set;
    auto it = set.begin();
    for (int i = 0; i < n_operations; ++i)
        it = set.emplace_hint(it, i);
    return set.size();
}
double time_it(std::function<std::size_t()> set_test,
               const char* what = nullptr,
               double ratio = 0.0)
{
    const auto start = std::chrono::system_clock::now();
    const std::size_t setsize = set_test();
    const auto stop = std::chrono::system_clock::now();
    const std::chrono::duration<double, std::milli> time = stop - start;
    if (what != nullptr && setsize > 0)
        std::cout << std::setw(8) << time << " pour " << what << " (ratio : "
                  << (ratio == 0.0 ? 1.0 : ratio / time.count()) << ")\n";
    return time.count();
}
int main()
{
    std::cout << std::fixed << std::setprecision(2);
    time_it(set_emplace); // préchauffage du cache
    const auto x = time_it(set_emplace, "plain emplace");
    time_it(set_emplace_hint, "emplace avec l'indice correct", x);
    time_it(set_emplace_hint_wrong, "emplace avec un indice incorrect", x);
    time_it(set_emplace_hint_corrected, "emplacement corrigé", x);
    time_it(set_emplace_hint_closest, "emplace en utilisant l'itérateur retourné", x);
}

Sortie possible :

146.88ms pour emplace simple (ratio : 1.00)
168.20ms pour emplace avec indice correct (ratio : 0.87)
168.78ms pour emplace avec indice erroné (ratio : 0.87)
166.58ms pour emplace corrigé (ratio : 0.88)
168.27ms pour emplace utilisant l'itérateur retourné (ratio : 0.87)

Voir aussi

construit un élément en place
(fonction membre publique)
insère des éléments ou des nœuds (depuis C++17)
(fonction membre publique)