Search code examples
c++templatesc++17

Use the type of a template parameter as key for a map<"type", int>


I mean to setup a map m where keys are variable types, and values are ints (I can change this later). Then, in a templated function (which is not a class member), with a simplified example

template<typename T>
void foo(vector<T>& v) {
    int type_idx = m[T];   // How to use this?
    const int n = v.size();
    foo2(type_idx, n);
    return;
}

Can this be done? How is the step for defining m, and how is the step for using it?

A rudimentary form is with


    if constexpr (std::is_same_v<T, int>) {
        foo2(1, n);
    } else if constexpr (std::is_same_v<T, double>) {
        foo2(2, n);
    } else if ...
    } else {
        myprintf("Not implemented for type %s", T);
    }

which corresponds to m[int] = 1, m[double] = 2, ... But this is more cumbersome than the way I mean to implement (if possible).

As for the correct way of printing T, I can find something.


Solution

  • You can use std::type_index. It is a wrapper of std::type_info that is intended to be used as key in a map. Objects of type std::type_info are generated using the typeid operator.

    Then your function and map look like this:

    #include <typeinfo>
    #include <typeindex>
    #include <map>
    #include <vector>
    
    void foo2(int, int);
    
    std::map<std::type_index, int> m{
        { typeid(int), 1 },
        { typeid(double), 2 },
    };
    
    template<typename T>
    void foo(std::vector<T>& v)
    {
        int type_idx = m[typeid(T)];
    
        const int n = v.size();
        foo2(type_idx, n);
    }