#include <iostream>
using std::cout;
#include <memory>
using std::unique_ptr;
#include <vector>
using std::vector;
class Base{ public: virtual ~Base() {}; };
class A : public Base { public: virtual ~A() {} };
class B : public Base { public: virtual ~B() {} };
class C : public Base { public: virtual ~C() {} };
void f(Base* b) { cout << "Calling Base :(\n"; }
void f(A* a) { cout << "It is an A!\n"; }
void f(B* b) { cout << "It is a B\n"; }
void f(C* c) { cout << "It is a C!\n"; }
template<class Derived>
void push(vector<unique_ptr<Base>>& v, Derived* obj)
{
v.push_back(std::unique_ptr<Derived>{obj});
}
int main() {
vector<unique_ptr<Base>> v{};
push(v, new A{});
push(v, new B{});
push(v, new C{});
for(auto& obj : v)
{
f(obj.get());
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgogIHVzaW5nIHN0ZDo6Y291dDsKIAojaW5jbHVkZSA8bWVtb3J5PgogIHVzaW5nIHN0ZDo6dW5pcXVlX3B0cjsKICAKI2luY2x1ZGUgPHZlY3Rvcj4KICB1c2luZyBzdGQ6OnZlY3RvcjsKICAKY2xhc3MgQmFzZXsgcHVibGljOiB2aXJ0dWFsIH5CYXNlKCkge307IH07CmNsYXNzIEEgOiBwdWJsaWMgQmFzZSB7IHB1YmxpYzogdmlydHVhbCB+QSgpIHt9IH07CmNsYXNzIEIgOiBwdWJsaWMgQmFzZSB7IHB1YmxpYzogdmlydHVhbCB+QigpIHt9IH07CmNsYXNzIEMgOiBwdWJsaWMgQmFzZSB7IHB1YmxpYzogdmlydHVhbCB+QygpIHt9IH07Cgp2b2lkIGYoQmFzZSogYikgeyBjb3V0IDw8ICJDYWxsaW5nIEJhc2UgOihcbiI7IH0Kdm9pZCBmKEEqIGEpIHsgY291dCA8PCAiSXQgaXMgYW4gQSFcbiI7IH0Kdm9pZCBmKEIqIGIpIHsgY291dCA8PCAiSXQgaXMgYSBCXG4iOyB9CnZvaWQgZihDKiBjKSB7IGNvdXQgPDwgIkl0IGlzIGEgQyFcbiI7IH0KCnRlbXBsYXRlPGNsYXNzIERlcml2ZWQ+CnZvaWQgcHVzaCh2ZWN0b3I8dW5pcXVlX3B0cjxCYXNlPj4mIHYsIERlcml2ZWQqIG9iaikKewoJdi5wdXNoX2JhY2soc3RkOjp1bmlxdWVfcHRyPERlcml2ZWQ+e29ian0pOwp9CgppbnQgbWFpbigpIHsKCXZlY3Rvcjx1bmlxdWVfcHRyPEJhc2U+PiB2e307CglwdXNoKHYsIG5ldyBBe30pOwoJcHVzaCh2LCBuZXcgQnt9KTsKCXB1c2godiwgbmV3IEN7fSk7CgkKCWZvcihhdXRvJiBvYmogOiB2KQoJewoJCWYob2JqLmdldCgpKTsKCX0KCQoJcmV0dXJuIDA7Cn0=