c++template-meta-programmingcompile-timetype-mapping

C++ How to implement a compile time mapping from types to types?


Is there a canonical/reference implementation of a compile time map, which maps types to types?

For example, I would need a type mapping from IBar -> IFoo or from int -> IFoo.

At compile time I can then select IFoo when given a IBar.

How would one go about this with C++17?

Edit: here is an example using structs https://godbolt.org/z/EEvrYd9PE


Solution

  • You could define one with overloading and return types. This will act like a map data structure that you can initialize and reuse with many types for many purposes.

    template<typename T>
    struct type_tag {
        using type = T;
    };
    
    template<typename K, typename V>
    struct pair {
        using first_type = K;
        using second_type = V;
    };
    
    template<typename Pair>
    struct element {
        static auto value(type_tag<typename Pair::first_type>) -> type_tag<typename Pair::second_type>;
    };
    
    template<typename... elems>
    struct type_map : element<elems>... {
        using element<elems>::value...;
    
        template<typename K>
        using find = typename decltype(type_map::value(type_tag<K>{}))::type;
    };
    

    You can use it like this:

    using my_map = type_map<
        pair<int, float>,
        pair<char, double>,
        pair<long, short>
    >;
    
    static_assert(std::is_same_v<my_map::find<int>, float>);
    static_assert(std::is_same_v<my_map::find<char>, double>);
    static_assert(std::is_same_v<my_map::find<long>, short>);
    

    Live example

    It should be quite fast as the lookup is limited to the scope of the class only, and uses the compilers own overload resolution.