Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a template work with both std::map and std::unordered_map

Tags:

c++

I have the following template function that returns a copy of the given map with swapped keys and values:

template<typename M>
auto swapKeysAndValues(const M& m) {
    std::map<typename M::mapped_type, typename M::key_type> swapped;
    for (auto& p : m) {
        swapped.emplace(p.second, p.first);
    }
    return swapped;
}

Is there a way of making the above template work for both std::map and std::unordered_map? That is, for std::map<K, V>, it should return std::map<V, K>, and for std::unordered_map<K, V>, it should return std::unordered_map<V, K>.

like image 599
s3rvac Avatar asked Oct 24 '15 07:10

s3rvac


People also ask

What is the difference between std::map and std :: unordered_map?

map is used to store elements as key,value pairs in sorted order. unordered_map is used to store elements as key,value pairs in non-sorted order.

Which is faster map or unordered map?

The unordered_map is the fastest in most of the cases in C++. The map however is faster in some of the cases.

Should I use unordered_map or map?

Contrarily, unordered_map has a big array (these can get quite big in some implementations), and then additional memory for each object. If you need to be memory-aware, map should prove better, because it lacks the large array. So, if you need pure lookup-retrieval, I'd say unordered_map is the way to go.

For which use cases map will win over unordered_map?

For searching an element, std::unordered_map gives the complexity O(1) in best case but O(n) in worst case (if hash implementation is not perfect). So, if your hash implementation is not good and you have millions and billions of data then go for std::map because it will give you guaranteed O(log N).


2 Answers

template<template <typename...> class Map, typename K, typename V>
auto swapKeyValues(const Map<K, V>& map)
{
    Map<V, K> result;
    for (const auto& p : map) result.emplace(p.second, p.first);
    return result;
}

Live example

like image 185
ForEveR Avatar answered Sep 29 '22 04:09

ForEveR


There are a couple of answers here so I'm not going to cover old ground.

There is however an aspect of this that you ought to consider carefully.

unordered maps are not the same as maps - they have the requirement that a hash function exists for the key (in addition to the equality predicate). As we have seen, it's trivial to write a template function that assumes the defaults, but is that what you want?

If both your K and V have hash functions available, then they are already keys. In that case, isn't what you really wanted a boost::bimap or boost::multi_index_map?

like image 31
Richard Hodges Avatar answered Sep 29 '22 04:09

Richard Hodges