#include <algorithm>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
class A : public std::enable_shared_from_this<A>
{};
class B : public A
{
public:
void doReallyCoolStuff();
};
void doCoolStuff(std::weak_ptr<A> obj)
{
std::cout << "cool A\n";
}
void doCoolStuff(std::weak_ptr<B> obj)
{
std::cout << "cool B\n";
doCoolStuff(std::static_pointer_cast<A>(obj.lock()));
}
void B::doReallyCoolStuff()
{
doCoolStuff(std::weak_ptr<B>(std::static_pointer_cast<B>(shared_from_this())));
}
int main()
{
auto b = std::make_shared<B>();
b->doReallyCoolStuff();
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dXRpbGl0eT4KCgpjbGFzcyBBIDogcHVibGljIHN0ZDo6ZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8QT4Ke307CgpjbGFzcyBCIDogcHVibGljIEEKewpwdWJsaWM6Cgl2b2lkIGRvUmVhbGx5Q29vbFN0dWZmKCk7Cn07IAoKdm9pZCBkb0Nvb2xTdHVmZihzdGQ6OndlYWtfcHRyPEE+IG9iaikKewoJc3RkOjpjb3V0IDw8ICJjb29sIEFcbiI7Cn0KCnZvaWQgZG9Db29sU3R1ZmYoc3RkOjp3ZWFrX3B0cjxCPiBvYmopCnsKCXN0ZDo6Y291dCA8PCAiY29vbCBCXG4iOwogZG9Db29sU3R1ZmYoc3RkOjpzdGF0aWNfcG9pbnRlcl9jYXN0PEE+KG9iai5sb2NrKCkpKTsKfQoKdm9pZCBCOjpkb1JlYWxseUNvb2xTdHVmZigpCnsKCWRvQ29vbFN0dWZmKHN0ZDo6d2Vha19wdHI8Qj4oc3RkOjpzdGF0aWNfcG9pbnRlcl9jYXN0PEI+KHNoYXJlZF9mcm9tX3RoaXMoKSkpKTsKfQoKaW50IG1haW4oKQp7CglhdXRvIGIgPSBzdGQ6Om1ha2Vfc2hhcmVkPEI+KCk7CgliLT5kb1JlYWxseUNvb2xTdHVmZigpOwp9