#include <iostream>
#include <memory>
class parent {
public:
virtual std::string who() { return "parent"; }
virtual ~parent(){}
};
class child1 : public parent {
public:
std::string who() override { return "child1"; }
};
class child2 : public parent {
public:
std::string who() override { return "child2"; }
};
using fn_ptr = std::string (parent::*)();
using parent_ptr = std::shared_ptr<parent>;
std::string run(parent_ptr x, fn_ptr fnc)
{
return (x.get()->*fnc)();
}
int main()
{
parent_ptr c1 = std::make_shared<child1>();
parent_ptr c2 = std::make_shared<child2>();
fn_ptr who = &parent::who;
std::cout << run(c1, who) << '\n';
std::cout << run(c2, who) << '\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgoKY2xhc3MgcGFyZW50IHsKCXB1YmxpYzoKCQl2aXJ0dWFsIHN0ZDo6c3RyaW5nIHdobygpIHsgcmV0dXJuICJwYXJlbnQiOyB9CgkJdmlydHVhbCB+cGFyZW50KCl7fQp9OwoKY2xhc3MgY2hpbGQxIDogcHVibGljIHBhcmVudCB7CglwdWJsaWM6CgkJc3RkOjpzdHJpbmcgd2hvKCkgb3ZlcnJpZGUgeyByZXR1cm4gImNoaWxkMSI7IH0KfTsKCmNsYXNzIGNoaWxkMiA6IHB1YmxpYyBwYXJlbnQgewoJcHVibGljOgoJCXN0ZDo6c3RyaW5nIHdobygpIG92ZXJyaWRlIHsgcmV0dXJuICJjaGlsZDIiOyB9Cn07Cgp1c2luZyBmbl9wdHIgPSBzdGQ6OnN0cmluZyAocGFyZW50OjoqKSgpOwp1c2luZyBwYXJlbnRfcHRyID0gc3RkOjpzaGFyZWRfcHRyPHBhcmVudD47CgpzdGQ6OnN0cmluZyBydW4ocGFyZW50X3B0ciB4LCBmbl9wdHIgZm5jKQp7CglyZXR1cm4gKHguZ2V0KCktPipmbmMpKCk7Cn0KCmludCBtYWluKCkKewoJcGFyZW50X3B0ciBjMSA9IHN0ZDo6bWFrZV9zaGFyZWQ8Y2hpbGQxPigpOwoJcGFyZW50X3B0ciBjMiA9IHN0ZDo6bWFrZV9zaGFyZWQ8Y2hpbGQyPigpOwoJZm5fcHRyIHdobyA9ICZwYXJlbnQ6OndobzsKCglzdGQ6OmNvdXQgPDwgcnVuKGMxLCB3aG8pIDw8ICdcbic7CglzdGQ6OmNvdXQgPDwgcnVuKGMyLCB3aG8pIDw8ICdcbic7Cn0K