#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <type_traits>
struct IFactory {
typedef std::shared_ptr<IFactory> SharedFactory;
virtual std::string Name() {
return "IFactory";
}
template<class... Arg>
SharedFactory Dup(const Arg&... A) {
return std::make_shared<std::remove_reference<decltype(*this)>::type>(A...);
}
enum {
ClassIFactory, ClassA, ClassB,
};
bool Say() {
std::cout << "Hoge" << X << std::endl;
return true;
}
int X = 123;
IFactory() {
std::cout << "IFactory() called. X=" << X << std::endl;
}
};
class A : public IFactory {
public:
std::string Name() {
return "A";
}
bool Say() {
std::cout << "Baw" << X << std::endl;
return true;
}
int X = 0;
A() {
std::cout << "A() called. X=" << X << std::endl;
}
};
class B : public IFactory {
public:
std::string Name() {
return "B";
}
bool Say() {
std::cout << "Maw" << X << std::endl;
return true;
}
char X = 0;
B() {
std::cout << "B() called. X=" << X << std::endl;
}
};
typedef std::vector<IFactory::SharedFactory> FType;
FType MakeVector() {
FType F = { std::make_shared<IFactory>(), std::make_shared<A>(), std::make_shared<B>() };
return F;
}
int main()
{
FType F = MakeVector();
auto X = F[IFactory::ClassIFactory]->Dup();
std::cout << X->Name() << std::endl;
std::cout << X->Say() << std::endl;
A* AA = static_cast<A*>(&(*X));
std::cout << AA->Name() << std::endl;
std::cout << AA->Say() << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpzdHJ1Y3QgSUZhY3RvcnkgewogIHR5cGVkZWYgc3RkOjpzaGFyZWRfcHRyPElGYWN0b3J5PiBTaGFyZWRGYWN0b3J5OwogIHZpcnR1YWwgc3RkOjpzdHJpbmcgTmFtZSgpIHsKICAgIHJldHVybiAiSUZhY3RvcnkiOwogIH0KICB0ZW1wbGF0ZTxjbGFzcy4uLiBBcmc+CiAgU2hhcmVkRmFjdG9yeSBEdXAoY29uc3QgQXJnJi4uLiBBKSB7CiAgICByZXR1cm4gc3RkOjptYWtlX3NoYXJlZDxzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8ZGVjbHR5cGUoKnRoaXMpPjo6dHlwZT4oQS4uLik7CiAgfQogIGVudW0gewogICAgQ2xhc3NJRmFjdG9yeSwgQ2xhc3NBLCBDbGFzc0IsCiAgfTsKICBib29sIFNheSgpIHsKICAgIHN0ZDo6Y291dCA8PCAiSG9nZSIgPDwgWCA8PCBzdGQ6OmVuZGw7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaW50IFggPSAxMjM7CiAgSUZhY3RvcnkoKSB7CiAgICBzdGQ6OmNvdXQgPDwgIklGYWN0b3J5KCkgY2FsbGVkLiBYPSIgPDwgWCA8PCBzdGQ6OmVuZGw7CiAgfQp9OwoKY2xhc3MgQSA6IHB1YmxpYyBJRmFjdG9yeSB7CnB1YmxpYzoKICBzdGQ6OnN0cmluZyBOYW1lKCkgewogICAgcmV0dXJuICJBIjsKICB9CiAgYm9vbCBTYXkoKSB7CiAgICBzdGQ6OmNvdXQgPDwgIkJhdyIgPDwgWCA8PCBzdGQ6OmVuZGw7CiAgICByZXR1cm4gdHJ1ZTsKICB9CiAgaW50IFggPSAwOwogIEEoKSB7CiAgICBzdGQ6OmNvdXQgPDwgIkEoKSBjYWxsZWQuIFg9IiA8PCBYIDw8IHN0ZDo6ZW5kbDsKICB9Cn07CgpjbGFzcyBCIDogcHVibGljIElGYWN0b3J5IHsKcHVibGljOgogIHN0ZDo6c3RyaW5nIE5hbWUoKSB7CiAgICByZXR1cm4gIkIiOwogIH0KICBib29sIFNheSgpIHsKICAgIHN0ZDo6Y291dCA8PCAiTWF3IiA8PCBYIDw8IHN0ZDo6ZW5kbDsKICAgIHJldHVybiB0cnVlOwogIH0KICBjaGFyIFggPSAwOwogIEIoKSB7CiAgICBzdGQ6OmNvdXQgPDwgIkIoKSBjYWxsZWQuIFg9IiA8PCBYIDw8IHN0ZDo6ZW5kbDsKICB9Cn07Cgp0eXBlZGVmIHN0ZDo6dmVjdG9yPElGYWN0b3J5OjpTaGFyZWRGYWN0b3J5PiBGVHlwZTsKCkZUeXBlIE1ha2VWZWN0b3IoKSB7CiAgRlR5cGUgRiA9IHsgc3RkOjptYWtlX3NoYXJlZDxJRmFjdG9yeT4oKSwgc3RkOjptYWtlX3NoYXJlZDxBPigpLCBzdGQ6Om1ha2Vfc2hhcmVkPEI+KCkgfTsKCiAgcmV0dXJuIEY7Cn0KCmludCBtYWluKCkKewogIEZUeXBlIEYgPSBNYWtlVmVjdG9yKCk7CgogIGF1dG8gWCA9IEZbSUZhY3Rvcnk6OkNsYXNzSUZhY3RvcnldLT5EdXAoKTsKCiAgc3RkOjpjb3V0IDw8IFgtPk5hbWUoKSA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8IFgtPlNheSgpIDw8IHN0ZDo6ZW5kbDsKCiAgQSogQUEgPSBzdGF0aWNfY2FzdDxBKj4oJigqWCkpOwoKICBzdGQ6OmNvdXQgPDwgQUEtPk5hbWUoKSA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8IEFBLT5TYXkoKSA8PCBzdGQ6OmVuZGw7Cn0K