#include <iostream>
#include <map>
#include <string>
template<typename T>
class AT
{
public:
virtual T get() const = 0;
};
class IT : public AT<int>
{
public:
int get() const { std::cout << "IT get" << std::endl; return 1; }
};
class ST : public AT<std::string>
{
public:
std::string get() const { std::cout << "ST get" << std::endl; return "ST"; }
};
class A
{
public:
A(){}
virtual ~A() {}
//protected:
void common() { std::cout << "A common" << std::endl; }
};
class B : public A , public IT
{
public:
B(){}
virtual ~B() {}
void get() { IT::get(); }
};
class C : public A , public ST
{
public:
C(){}
virtual ~C(){}
void get() { ST::get(); }
};
enum TYPE { NUMBER, STRING };
int main()
{
std::map<int, A*(*)()> makeAMap;
makeAMap[NUMBER] = []() -> A* { std::cout << "making B" << std::endl; return new B; };
makeAMap[STRING] = []() -> A* { std::cout << "making C" << std::endl; return new C; };
//...
std::map<int, void(*)(A*)> getFuncMap;
getFuncMap[NUMBER] = [](A *item){ static_cast<B*>(item)->get(); };
getFuncMap[STRING] = [](A *item){ static_cast<C*>(item)->get(); };
//...
int type;
A* item;
type = 0;
item = makeAMap[type]();
//...
item->common();
getFuncMap[type](item);
//...
delete item;
type = 1;
item = makeAMap[type]();
//...
item->common();
getFuncMap[type](item);
//...
delete item;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8c3RyaW5nPgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgQVQKewpwdWJsaWM6CiAgICB2aXJ0dWFsIFQgZ2V0KCkgY29uc3QgPSAwOwp9OwoKY2xhc3MgSVQgOiBwdWJsaWMgQVQ8aW50Pgp7CnB1YmxpYzoKICAgIGludCBnZXQoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiSVQgZ2V0IiA8PCBzdGQ6OmVuZGw7IHJldHVybiAxOyB9Cn07CgpjbGFzcyBTVCA6IHB1YmxpYyBBVDxzdGQ6OnN0cmluZz4KewpwdWJsaWM6CiAgICBzdGQ6OnN0cmluZyBnZXQoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiU1QgZ2V0IiA8PCBzdGQ6OmVuZGw7IHJldHVybiAiU1QiOyB9Cn07CgpjbGFzcyBBCnsKcHVibGljOgogICAgQSgpe30KICAgIHZpcnR1YWwgfkEoKSB7fQovL3Byb3RlY3RlZDoKICAgIHZvaWQgY29tbW9uKCkgeyBzdGQ6OmNvdXQgPDwgIkEgY29tbW9uIiA8PCBzdGQ6OmVuZGw7IH0KfTsKCmNsYXNzIEIgOiBwdWJsaWMgQSAsIHB1YmxpYyBJVAp7CnB1YmxpYzoKICAgIEIoKXt9CiAgICB2aXJ0dWFsIH5CKCkge30KICAgIHZvaWQgZ2V0KCkgeyBJVDo6Z2V0KCk7IH0KfTsKCmNsYXNzIEMgOiBwdWJsaWMgQSAsIHB1YmxpYyBTVAp7CnB1YmxpYzoKICAgIEMoKXt9CiAgICB2aXJ0dWFsIH5DKCl7fQogICAgdm9pZCBnZXQoKSB7IFNUOjpnZXQoKTsgfQp9OwoKZW51bSBUWVBFIHsgTlVNQkVSLCBTVFJJTkcgfTsKCmludCBtYWluKCkKewoJc3RkOjptYXA8aW50LCBBKigqKSgpPiBtYWtlQU1hcDsKCW1ha2VBTWFwW05VTUJFUl0gPSBbXSgpIC0+IEEqIHsgc3RkOjpjb3V0IDw8ICJtYWtpbmcgQiIgPDwgc3RkOjplbmRsOyByZXR1cm4gbmV3IEI7IH07CgltYWtlQU1hcFtTVFJJTkddID0gW10oKSAtPiBBKiB7IHN0ZDo6Y291dCA8PCAibWFraW5nIEMiIDw8IHN0ZDo6ZW5kbDsgcmV0dXJuIG5ldyBDOyB9OwoJLy8uLi4KICAgIAoJc3RkOjptYXA8aW50LCB2b2lkKCopKEEqKT4gZ2V0RnVuY01hcDsKCWdldEZ1bmNNYXBbTlVNQkVSXSA9IFtdKEEgKml0ZW0peyBzdGF0aWNfY2FzdDxCKj4oaXRlbSktPmdldCgpOyB9OwoJZ2V0RnVuY01hcFtTVFJJTkddID0gW10oQSAqaXRlbSl7IHN0YXRpY19jYXN0PEMqPihpdGVtKS0+Z2V0KCk7IH07CgkvLy4uLgoKICAgIGludCB0eXBlOwoJQSogaXRlbTsKCiAgICB0eXBlID0gMDsKCWl0ZW0gPSBtYWtlQU1hcFt0eXBlXSgpOwoJLy8uLi4KCWl0ZW0tPmNvbW1vbigpOyAgICAKCWdldEZ1bmNNYXBbdHlwZV0oaXRlbSk7CgkvLy4uLgoJZGVsZXRlIGl0ZW07CgogICAgdHlwZSA9IDE7CglpdGVtID0gbWFrZUFNYXBbdHlwZV0oKTsKCS8vLi4uCglpdGVtLT5jb21tb24oKTsgICAgCglnZXRGdW5jTWFwW3R5cGVdKGl0ZW0pOwoJLy8uLi4KCWRlbGV0ZSBpdGVtOwoKCXJldHVybiAwOwp9