#include <map>
#include <iostream>
#include <utility>
#include <typeinfo>
#include <string>
class A {};
class B {};
struct type_forward
            {
                /// NOTE: Add more type-forwarding here
                struct type_impl
                {
                    typedef int key_type;
                };
                struct A_forward: public type_impl
                {
                    typedef A type;
                };
                struct B_forward: public type_impl
                {
                    typedef B type;
                };
                struct string_forward: public type_impl
                {
                    typedef std::string type;
                };
                static std::map<type_impl::key_type, type_impl> type_forwardings;
            };
std::map<type_forward::type_impl::key_type, type_forward::type_impl> type_forward::type_forwardings =
    std::map<type_forward::type_impl::key_type, type_forward::type_impl>();
int main()
{
    type_forward::type_forwardings.insert({1, type_forward::A_forward()});
    type_forward::type_forwardings.insert({2, type_forward::B_forward()});
    type_forward::type_forwardings.insert({3, type_forward::string_forward()});
    auto X(type_forward::type_forwardings.at(1));
    auto XX(type_forward::type_forwardings.at(2));
    auto XXX(type_forward::type_forwardings.at(3));

    decltype(X)::type Z; /// Z doit être de type A !
    decltype(XX)::type ZZ; /// ZZ doit être de type B !
    decltype(XXX)::type ZZZ; /// ZZZ doit être de type std::string !
}