简体   繁体   中英

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

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);

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.

Hmmm... Simply search for the value before?

auto it = map.find(k);
if (it == map.end()){ //value does not exist
    auto newIt = map.emplace({std::move(k),std::forward<Args>(args)...});
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM