#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 !
}
I2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8c3RyaW5nPgpjbGFzcyBBIHt9OwpjbGFzcyBCIHt9OwpzdHJ1Y3QgdHlwZV9mb3J3YXJkCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vLyBOT1RFOiBBZGQgbW9yZSB0eXBlLWZvcndhcmRpbmcgaGVyZQogICAgICAgICAgICAgICAgc3RydWN0IHR5cGVfaW1wbAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHR5cGVkZWYgaW50IGtleV90eXBlOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIHN0cnVjdCBBX2ZvcndhcmQ6IHB1YmxpYyB0eXBlX2ltcGwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0eXBlZGVmIEEgdHlwZTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBzdHJ1Y3QgQl9mb3J3YXJkOiBwdWJsaWMgdHlwZV9pbXBsCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdHlwZWRlZiBCIHR5cGU7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgc3RydWN0IHN0cmluZ19mb3J3YXJkOiBwdWJsaWMgdHlwZV9pbXBsCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdHlwZWRlZiBzdGQ6OnN0cmluZyB0eXBlOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIHN0YXRpYyBzdGQ6Om1hcDx0eXBlX2ltcGw6OmtleV90eXBlLCB0eXBlX2ltcGw+IHR5cGVfZm9yd2FyZGluZ3M7CiAgICAgICAgICAgIH07CnN0ZDo6bWFwPHR5cGVfZm9yd2FyZDo6dHlwZV9pbXBsOjprZXlfdHlwZSwgdHlwZV9mb3J3YXJkOjp0eXBlX2ltcGw+IHR5cGVfZm9yd2FyZDo6dHlwZV9mb3J3YXJkaW5ncyA9CiAgICBzdGQ6Om1hcDx0eXBlX2ZvcndhcmQ6OnR5cGVfaW1wbDo6a2V5X3R5cGUsIHR5cGVfZm9yd2FyZDo6dHlwZV9pbXBsPigpOwppbnQgbWFpbigpCnsKICAgIHR5cGVfZm9yd2FyZDo6dHlwZV9mb3J3YXJkaW5ncy5pbnNlcnQoezEsIHR5cGVfZm9yd2FyZDo6QV9mb3J3YXJkKCl9KTsKICAgIHR5cGVfZm9yd2FyZDo6dHlwZV9mb3J3YXJkaW5ncy5pbnNlcnQoezIsIHR5cGVfZm9yd2FyZDo6Ql9mb3J3YXJkKCl9KTsKICAgIHR5cGVfZm9yd2FyZDo6dHlwZV9mb3J3YXJkaW5ncy5pbnNlcnQoezMsIHR5cGVfZm9yd2FyZDo6c3RyaW5nX2ZvcndhcmQoKX0pOwogICAgYXV0byBYKHR5cGVfZm9yd2FyZDo6dHlwZV9mb3J3YXJkaW5ncy5hdCgxKSk7CiAgICBhdXRvIFhYKHR5cGVfZm9yd2FyZDo6dHlwZV9mb3J3YXJkaW5ncy5hdCgyKSk7CiAgICBhdXRvIFhYWCh0eXBlX2ZvcndhcmQ6OnR5cGVfZm9yd2FyZGluZ3MuYXQoMykpOwoKICAgIGRlY2x0eXBlKFgpOjp0eXBlIFo7IC8vLyBaIGRvaXQgw6p0cmUgZGUgdHlwZSBBICEKICAgIGRlY2x0eXBlKFhYKTo6dHlwZSBaWjsgLy8vIFpaIGRvaXQgw6p0cmUgZGUgdHlwZSBCICEKICAgIGRlY2x0eXBlKFhYWCk6OnR5cGUgWlpaOyAvLy8gWlpaIGRvaXQgw6p0cmUgZGUgdHlwZSBzdGQ6OnN0cmluZyAhCn0=