#include <iostream>
#include <string>
template <typename C>
class Super
{
public:
std::string GetFunnyName() const
{
C *thiz = static_cast<C *>(this);
return thiz->GetFunnyName();
}
};
template <typename C>
class A_base : public Super<C>
{
public:
std::string GetFunnyName() const
{
return "A";
}
};
class A : public A_base<A> { };
class B : public A_base<B>
{
public:
std::string GetFunnyName() const
{
return "B";
}
};
template <typename TSuper>
void OutputFunny(const TSuper &obj)
{
std::cout << obj.GetFunnyName() << "\n";
}
int main()
{
A a;
B b;
OutputFunny(a);
OutputFunny(b);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgoKdGVtcGxhdGUgPHR5cGVuYW1lIEM+CmNsYXNzIFN1cGVyCnsKcHVibGljOgogICAgc3RkOjpzdHJpbmcgR2V0RnVubnlOYW1lKCkgY29uc3QKICAgIHsKICAgICAgICBDICp0aGl6ID0gc3RhdGljX2Nhc3Q8QyAqPih0aGlzKTsKICAgICAgICByZXR1cm4gdGhpei0+R2V0RnVubnlOYW1lKCk7CiAgICB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQz4KY2xhc3MgQV9iYXNlIDogcHVibGljIFN1cGVyPEM+CnsKcHVibGljOgogICAgc3RkOjpzdHJpbmcgR2V0RnVubnlOYW1lKCkgY29uc3QKICAgIHsKICAgICAgICByZXR1cm4gIkEiOwogICAgfQp9OwpjbGFzcyBBIDogcHVibGljIEFfYmFzZTxBPiB7IH07CgpjbGFzcyBCIDogcHVibGljIEFfYmFzZTxCPgp7CnB1YmxpYzoKICAgIHN0ZDo6c3RyaW5nIEdldEZ1bm55TmFtZSgpIGNvbnN0CiAgICB7CiAgICAgICAgcmV0dXJuICJCIjsKICAgIH0KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUU3VwZXI+CnZvaWQgT3V0cHV0RnVubnkoY29uc3QgVFN1cGVyICZvYmopCnsKICAgIHN0ZDo6Y291dCA8PCBvYmouR2V0RnVubnlOYW1lKCkgPDwgIlxuIjsKfQoKaW50IG1haW4oKQp7CiAgICBBIGE7CiAgICBCIGI7CgogICAgT3V0cHV0RnVubnkoYSk7CiAgICBPdXRwdXRGdW5ueShiKTsKfQ==