And because we love pain, here come the CRTP diamond derive.
Have fun with these. (no, don't)
#include <iostream> using namespace std; template<typename Child, typename Child2> struct UltraBase : public Child, public Child2 { void func() { cout << "UltraBase\n"; static_cast<Child*>(this)->func(); } void func2() { cout << "UltraBase\n"; static_cast<Child2*>(this)->func2(); } }; template<typename Child> struct Base : public Child { void func() { cout << "Base\n"; static_cast<Child*>(this)->func(); } }; template<typename Child> struct Base2 : public Child { void func2() { cout << "Base2\n"; static_cast<Child*>(this)->func2(); } }; struct Child { void func() { cout << "Child\n"; } void func2() { cout << "Child2\n"; } }; int main() { UltraBase<Base<Child>, Base2<Child>> ultrabase; ultrabase.func(); ultrabase.func2(); }
UltraBase Base Child UltraBase Base2 Child2