#include <iostream>
#include <unordered_map>
#include <typeindex>
#include <functional>

using namespace std;

struct Container {

    template <class I, class C>
    void assoc() {
        generators[typeid(I)] = []() -> C * { return new C; };
    }

    template <class I>
    I * get() {
        auto g = generators[typeid(I)];
        return g ? static_cast<I *>(g()) : 0;
    }

    unordered_map<type_index, function<void *(void)>> generators;
};

struct IVehicle {
    virtual void sayHello() = 0;
};

struct Car : IVehicle {
    void sayHello() override { cout << "Hello, I am a Car!" << endl; }
};

struct Bicycle : IVehicle {
    void sayHello() override { cout << "Hello, I am a Bicycle!" << endl; }
};

void test(Container & c) {

    auto v = c.get<IVehicle>();

    if (v) {
        v->sayHello();
    } else {
        cout << "Couldn't find vehicle :(" << endl;
    }

}

int main() {

    Container c;

    test(c);

    c.assoc<IVehicle, Car>();
    test(c);

    c.assoc<IVehicle, Bicycle>();
    test(c);

}