#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 {
ClassA,
ClassB,
};
};
class A :public IFactory {
public:
std::string Name() { return "A"; }
bool Say() { std::cout << "Baw"<<X << std::endl; return true; }
int X = 0;
};
class B :public IFactory {
public:
std::string Name() { return "B"; }
bool Say() { std::cout << "Maw" << X << std::endl; return true; }
char X = 0;
};
typedef std::vector<IFactory::SharedFactory> FType;
FType MakeVector() {
FType F = { std::make_shared<A>() ,std::make_shared<B>() };
return F;
}
int main() {
FType F = MakeVector();
auto X = F[IFactory::ClassA]->Dup();
A* AA = static_cast<A*>(&(*X));
std::cout <<AA->Name() << std::endl;
std::cout <<AA->Say() << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgoKc3RydWN0IElGYWN0b3J5IHsKCXR5cGVkZWYgc3RkOjpzaGFyZWRfcHRyPElGYWN0b3J5PiBTaGFyZWRGYWN0b3J5OwoJdmlydHVhbCBzdGQ6OnN0cmluZyBOYW1lKCkgeyByZXR1cm4gIklGYWN0b3J5IjsgfQoKCXRlbXBsYXRlPGNsYXNzLi4uIEFyZz4KCVNoYXJlZEZhY3RvcnkgRHVwKGNvbnN0IEFyZyYuLi4gQSkgewoJCXJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZTxkZWNsdHlwZSgqdGhpcyk+Ojp0eXBlPihBLi4uKTsKCX0KCgllbnVtIHsKCQlDbGFzc0EsCgkJQ2xhc3NCLAoJfTsKfTsKCmNsYXNzIEEgOnB1YmxpYyBJRmFjdG9yeSB7CnB1YmxpYzoKCXN0ZDo6c3RyaW5nIE5hbWUoKSB7IHJldHVybiAiQSI7IH0KCWJvb2wgU2F5KCkgeyBzdGQ6OmNvdXQgPDwgIkJhdyI8PFggPDwgc3RkOjplbmRsOyByZXR1cm4gdHJ1ZTsgfQoJaW50IFggPSAwOwp9OwoKY2xhc3MgQiA6cHVibGljIElGYWN0b3J5IHsKcHVibGljOgoJc3RkOjpzdHJpbmcgTmFtZSgpIHsgcmV0dXJuICJCIjsgfQoJYm9vbCBTYXkoKSB7IHN0ZDo6Y291dCA8PCAiTWF3IiA8PCBYIDw8IHN0ZDo6ZW5kbDsgcmV0dXJuIHRydWU7IH0KCWNoYXIgWCA9IDA7Cn07Cgp0eXBlZGVmIHN0ZDo6dmVjdG9yPElGYWN0b3J5OjpTaGFyZWRGYWN0b3J5PiBGVHlwZTsKCgpGVHlwZSBNYWtlVmVjdG9yKCkgewoJRlR5cGUgRiA9IHsgc3RkOjptYWtlX3NoYXJlZDxBPigpICxzdGQ6Om1ha2Vfc2hhcmVkPEI+KCkgfTsKCglyZXR1cm4gRjsKfQoKaW50IG1haW4oKSB7CglGVHlwZSBGID0gTWFrZVZlY3RvcigpOwoKCWF1dG8gWCA9IEZbSUZhY3Rvcnk6OkNsYXNzQV0tPkR1cCgpOwoKCUEqIEFBID0gc3RhdGljX2Nhc3Q8QSo+KCYoKlgpKTsKCglzdGQ6OmNvdXQgPDxBQS0+TmFtZSgpIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PEFBLT5TYXkoKSA8PCBzdGQ6OmVuZGw7CgoJcmV0dXJuIDA7Cn0=