Home > Mobile >  Using a type without template arguments as a template argument
Using a type without template arguments as a template argument

Time:12-03

I have a class named Registry which correlates an ID with some data. I would like to make it so the underlying structure which stores these pairs can be any std::mapish type, of which the user can define (e.g.: std::map, std::unordered_map).

My initial thought was to do something like this:

template<typename Value, typename Container, typename ID = size_t>
class Registry{
    using Storage = Container<ID, value>;
    static_assert(std::is_same<Storage, std::map> || std::is_same<Storage, std::map>, "Underlying storage type must be a std::map-ish.");
    public:
    Storage<ID, Value> store;
    ...

However, trying to use the class results in an error:

Registry<bool, std::map> testRegistry;
err) argument list for class template std::map is missing

I understand the compiler's complaint, but is there any way to work around it so that this syntax (or something similar) might work?

Thanks for the advice.

CodePudding user response:

You need to declare Container as a template template parameter. E.g.

template<typename Value, template <typename...> class Container, typename ID = size_t>
class Registry{

    using Storage = Container<ID, Value>;
    static_assert(std::is_same_v<Storage, std::map<ID, Value>> || std::is_same_v<Storage, std::unordered_map<ID, Value>>, "Underlying storage type must be a std::map-ish.");
    public:
    Storage store;
    ...

Other issues:

  • Storage is an instantiation, so don't specify template arguments for it.
  • Specify template arguments for std::map.
  • As the condition of static_assert you should use std::is_same_v (or std::is_same<...>::value instead.

CodePudding user response:

As alternative, you might provide only container, instead of key, value, and template container:

template <typename Container>
class Registry
{
    using ID = typename Container::key_type;
    using Value = typename Container::mapped_type;
    static_assert(std::is_same_v<Container, std::map<ID, Value>>
               || std::is_same_v<Container, std::unordered_map<ID, Value>>,
                  "Underlying storage type must be a std::map-ish.");
    // ...
};

With usage

Registry<std::map<std::size_t, bool>> testRegistry;
Registry<std::unordered_map<std::size_t, float>> testRegistry2;
  • Related