2

Is there a way to use a variadic template as a Key template parameter in std::unordered_map?

I tried to do it in this way:

template<typename T, typename ...Args>
class Wrapper {
public:
    // some staff
private:
    unordered_map<Args, T> hashmap;

};

But got this error:

Error C3520 'Args': parameter pack must be expanded in this context

Charles Ofria
  • 1,936
  • 12
  • 24
dolfin13
  • 25
  • 4

1 Answers1

1

Is there a way to use a variadic template as a Key template parameter in std::unordered_map?

No, as far I know: std::unordered_map require a single key type and a single value type.

But if your intention is to have a hashmap, in the Wrapper class, for every type in Args..., and if the Args... types are all different, you can obtain it through another inheritance and another level of wrapping

template <typename K, typename V>
struct wrpH
 { std::unordered_map<K, V> hashmap; };

template <typename T, typename ...Args>
class Wrapper : public wrpH<Args, T>...
 { };

The problem of this solution is that you have more hashmap in the same class and to access they you have to explicit the corresponding base struct; something as follows

w.wrpH<Args, T>::hashmap[argsValue] = tValue;

The following is a full working example

#include <iostream>
#include <unordered_map>

template <typename K, typename V>
struct wrpH
 { std::unordered_map<K, V> hashmap; };

template <typename T, typename ...Args>
class Wrapper : public wrpH<Args, T>...
 { };

int main()
 {
   Wrapper<int, int, long, long long>  w;

   w.wrpH<long, int>::hashmap[1L] = 2;

   std::cout << w.wrpH<int, int>::hashmap.size() << std::endl;
   std::cout << w.wrpH<long, int>::hashmap.size() << std::endl;
   std::cout << w.wrpH<long long, int>::hashmap.size() << std::endl;
 }

If, on the contrary, you need a single hashmap with a key that is a combination of all Args... types, you can use, as key type, a class that receive a variadic list of types as template paramenters. As suggested in comments, std::tuple is the obvious choice

std::unordered_map<std::tuple<Args...>, T> hashmap;

This works also if some types in Args... coincide.

max66
  • 65,235
  • 10
  • 71
  • 111
  • I needed a single `hashmap` with a key that is a combination of all `Args...` types. So the solution with `tuple` works for me. Thanks! – dolfin13 Jan 23 '18 at 17:41