#include <iostream>
#include <type_traits>
template <typename Derived>
struct A
{
static void do_thing() { Derived::do_thing(); }
};
struct B : public A<B>
{
friend A<B>;
protected:
static void do_thing() { std::cout << "B impl" << std::endl; }
};
struct C : public A<C>
{
friend A<C>;
protected:
static void do_thing() { std::cout << "C impl" << std::endl; }
};
int main()
{
A<B>::do_thing();
A<C>::do_thing();
return (0);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRGVyaXZlZD4Kc3RydWN0IEEKewogc3RhdGljIHZvaWQgZG9fdGhpbmcoKSB7IERlcml2ZWQ6OmRvX3RoaW5nKCk7IH0KfTsKCnN0cnVjdCBCIDogcHVibGljIEE8Qj4KewogIGZyaWVuZCBBPEI+OwogcHJvdGVjdGVkOgogIHN0YXRpYyB2b2lkIGRvX3RoaW5nKCkgeyBzdGQ6OmNvdXQgPDwgIkIgaW1wbCIgPDwgc3RkOjplbmRsOyB9Cn07CgpzdHJ1Y3QgQyA6IHB1YmxpYyBBPEM+CnsKICBmcmllbmQgQTxDPjsKIHByb3RlY3RlZDoKICBzdGF0aWMgdm9pZCBkb190aGluZygpIHsgc3RkOjpjb3V0IDw8ICJDIGltcGwiIDw8IHN0ZDo6ZW5kbDsgfQp9OwoKaW50IG1haW4oKSAKewogQTxCPjo6ZG9fdGhpbmcoKTsKIEE8Qz46OmRvX3RoaW5nKCk7CiAKIHJldHVybiAoMCk7Cn0=