Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Re-implementing std::map::try_emplace() from C++17 in C++11?

Tags:

c++

c++11

stl

std::map::try_emplace() seems very convenient and efficient but it's only available in C++17. Is it possible to re-implement it in C++11?

template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
like image 519
Pol Avatar asked Dec 20 '15 14:12

Pol


1 Answers

For an ordered map, you can get close to the behaviour with lower_bound:

template <class M, class... Args>
std::pair<typename M::iterator, bool>
try_emplace_m(M& m, const typename M::key_type& k, Args&&... args) {
    auto it = m.lower_bound(k);
    if (it == m.end() || m.key_comp()(k, it->first)) {
        return {m.emplace_hint(
            it, std::piecewise_construct,
            std::forward_as_tuple(k),
            std::forward_as_tuple(std::forward<Args>(args)...)), true};
    }
    return {it, false};
}

For an unordered map, you can't use lower_bound. You can replace it with find, and the test with key_eq(), to get a functional version, which will perform a repeated lookup in the case of an insertion, though. Sp speaking purely in terms of algorithmic complexity this new member function pulls more weight in the unordered case, which users cannot currently implement using only the public API. But the added convenience applies equally to both cases.

like image 101
Kerrek SB Avatar answered Sep 21 '22 13:09

Kerrek SB