#include <iostream>
template< typename DT, typename... Bases > // C++11 variadic template
struct CRTP: private Bases...
{
friend DT; // C++11 extended friend
DT func( void ) { return DT(); }
};
struct A :
public CRTP< A >
{
int get() { return value; }
private:
int value = 4;
};
struct B :
public CRTP< B, A >
{
double get() { return value; }
private:
double value = 1.1;
};
int main()
{
A a;
B b;
std::cout << " a: " << a.get() << " b: " << b.get() << std::endl;
A aa = a.func();
std::cout << " aa: " << aa.get() << std::endl;
B bb = b.func();
std::cout << " bb: " << bb.get() << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8IHR5cGVuYW1lIERULCB0eXBlbmFtZS4uLiBCYXNlcyA+IC8vIEMrKzExIHZhcmlhZGljIHRlbXBsYXRlCnN0cnVjdCBDUlRQOiBwcml2YXRlIEJhc2VzLi4uCnsKCWZyaWVuZCBEVDsgLy8gQysrMTEgZXh0ZW5kZWQgZnJpZW5kCiAgICBEVCBmdW5jKCB2b2lkICkgeyByZXR1cm4gRFQoKTsgfQp9OwoKc3RydWN0IEEgOgogICAgcHVibGljIENSVFA8IEEgPiAKewogICAgaW50IGdldCgpIHsgcmV0dXJuIHZhbHVlOyB9CiAgICBwcml2YXRlOgogICAgICAgIGludCB2YWx1ZSA9IDQ7Cn07CgpzdHJ1Y3QgQiA6CiAgICBwdWJsaWMgQ1JUUDwgQiwgQSA+IAp7CiAgICBkb3VibGUgZ2V0KCkgeyByZXR1cm4gdmFsdWU7IH0KICAgIHByaXZhdGU6CiAgICAgICAgZG91YmxlIHZhbHVlID0gMS4xOwp9OwoKaW50IG1haW4oKQp7CiAgICBBIGE7CiAgICBCIGI7CiAgICBzdGQ6OmNvdXQgPDwgIiBhOiAiIDw8IGEuZ2V0KCkgPDwgIiBiOiAiIDw8IGIuZ2V0KCkgPDwgc3RkOjplbmRsOwogICAgQSBhYSA9IGEuZnVuYygpOwogICAgc3RkOjpjb3V0IDw8ICIgYWE6ICIgPDwgYWEuZ2V0KCkgPDwgc3RkOjplbmRsOwogICAgQiBiYiA9IGIuZnVuYygpOyAKICAgIHN0ZDo6Y291dCA8PCAiIGJiOiAiIDw8IGJiLmdldCgpIDw8IHN0ZDo6ZW5kbDsKfQ==