#include <iostream>
#include <string>
#include <map>
template<class ID,class Base,class ... Args> class GenericObjectFactory{
private:
typedef Base* (*fInstantiator)(Args ...);
template<class Derived> static Base* instantiator(Args ... args){
return new Derived(args ...);
}
std::map<ID,fInstantiator> classes;
public:
GenericObjectFactory(){}
template<class Derived> void add(ID id){
classes[id]=&instantiator<Derived>;
}
fInstantiator get(ID id){
return classes[id];
}
};
using namespace std;
class Animal{
public:
Animal(bool isAlive,string name) : isAlive(isAlive),name(name){};
bool isAlive;
string name;
virtual string voice() const=0;
};
class Dog : public Animal{
public:
using Animal::Animal;
string voice() const{
return this->isAlive?
"Woof! I'm "+this->name+"\n":
"";
}
};
class Cat : public Animal{
public:
using Animal::Animal;
string voice() const{
return this->isAlive?
"Meow, I'm "+this->name+"\n":
"";
}
};
int main(void){
GenericObjectFactory<string,Animal,bool,string> animalFactory;
animalFactory.add<Dog>("man's friend");
animalFactory.add<Cat>("^_^");
Animal *dog1=animalFactory.get("man's friend")(true,"charlie");
Animal *dog2=animalFactory.get("man's friend")(false,"fido");
Animal *cat =animalFactory.get("^_^")(true,"begemoth");
cout << dog1->voice()
<< dog2->voice()
<< cat ->voice();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8bWFwPgoKdGVtcGxhdGU8Y2xhc3MgSUQsY2xhc3MgQmFzZSxjbGFzcyAuLi4gQXJncz4gY2xhc3MgR2VuZXJpY09iamVjdEZhY3Rvcnl7CnByaXZhdGU6CiAgICB0eXBlZGVmIEJhc2UqICgqZkluc3RhbnRpYXRvcikoQXJncyAuLi4pOwogICAgdGVtcGxhdGU8Y2xhc3MgRGVyaXZlZD4gc3RhdGljIEJhc2UqIGluc3RhbnRpYXRvcihBcmdzIC4uLiBhcmdzKXsKICAgICAgICByZXR1cm4gbmV3IERlcml2ZWQoYXJncyAuLi4pOwogICAgfQogICAgc3RkOjptYXA8SUQsZkluc3RhbnRpYXRvcj4gY2xhc3NlczsKIApwdWJsaWM6CiAgICBHZW5lcmljT2JqZWN0RmFjdG9yeSgpe30KICAgIHRlbXBsYXRlPGNsYXNzIERlcml2ZWQ+IHZvaWQgYWRkKElEIGlkKXsKICAgICAgICBjbGFzc2VzW2lkXT0maW5zdGFudGlhdG9yPERlcml2ZWQ+OwogICAgfQogICAgZkluc3RhbnRpYXRvciBnZXQoSUQgaWQpewogICAgICAgIHJldHVybiBjbGFzc2VzW2lkXTsKICAgIH0KCn07Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwogICAgICAgICAKY2xhc3MgQW5pbWFsewpwdWJsaWM6CiAgICBBbmltYWwoYm9vbCBpc0FsaXZlLHN0cmluZyBuYW1lKSA6IGlzQWxpdmUoaXNBbGl2ZSksbmFtZShuYW1lKXt9OwogICAgYm9vbCBpc0FsaXZlOwogICAgc3RyaW5nIG5hbWU7CiAgICB2aXJ0dWFsIHN0cmluZyB2b2ljZSgpIGNvbnN0PTA7Cn07CmNsYXNzIERvZyA6IHB1YmxpYyBBbmltYWx7CnB1YmxpYzoKICAgIHVzaW5nIEFuaW1hbDo6QW5pbWFsOwogICAgc3RyaW5nIHZvaWNlKCkgY29uc3R7CiAgICAgICAgcmV0dXJuIHRoaXMtPmlzQWxpdmU/CiAgICAgICAgICAgICJXb29mISBJJ20gIit0aGlzLT5uYW1lKyJcbiI6CiAgICAgICAgICAgICIiOwogICAgfQp9OwpjbGFzcyBDYXQgOiBwdWJsaWMgQW5pbWFsewpwdWJsaWM6CiAgICB1c2luZyBBbmltYWw6OkFuaW1hbDsKICAgIHN0cmluZyB2b2ljZSgpIGNvbnN0ewogICAgCXJldHVybiB0aGlzLT5pc0FsaXZlPwogICAgICAgICAgICAiTWVvdywgSSdtICIrdGhpcy0+bmFtZSsiXG4iOgogICAgICAgICAgICAiIjsKICAgIH0KfTsKICAgICAgICAgCmludCBtYWluKHZvaWQpewogICAgR2VuZXJpY09iamVjdEZhY3Rvcnk8c3RyaW5nLEFuaW1hbCxib29sLHN0cmluZz4gYW5pbWFsRmFjdG9yeTsKICAgIAogICAgYW5pbWFsRmFjdG9yeS5hZGQ8RG9nPigibWFuJ3MgZnJpZW5kIik7CiAgICBhbmltYWxGYWN0b3J5LmFkZDxDYXQ+KCJeX14iKTsKICAgIAogICAgQW5pbWFsICpkb2cxPWFuaW1hbEZhY3RvcnkuZ2V0KCJtYW4ncyBmcmllbmQiKSh0cnVlLCJjaGFybGllIik7CiAgICBBbmltYWwgKmRvZzI9YW5pbWFsRmFjdG9yeS5nZXQoIm1hbidzIGZyaWVuZCIpKGZhbHNlLCJmaWRvIik7CiAgICBBbmltYWwgKmNhdCA9YW5pbWFsRmFjdG9yeS5nZXQoIl5fXiIpKHRydWUsImJlZ2Vtb3RoIik7CiAgICAKICAgIGNvdXQgPDwgZG9nMS0+dm9pY2UoKQogICAgICAgICA8PCBkb2cyLT52b2ljZSgpCiAgICAgICAgIDw8IGNhdCAtPnZvaWNlKCk7CiAgICByZXR1cm4gMDsKfQo=