Callbacks from private CRTP bases

c++

Solution

I think the best solution is to avoid private inheritance and instead opt for data hiding. Marking the member function protected will prevent access from everywhere except derived classes. A further bonus public inheritance is used instead.

template<typename T>
class CRTPBase {
protected:
  void callBase() {
    T * derived = static_cast<T*>(this);
    derived->publicMethod();
  }
};

struct Derived : public CRTPBase<Derived> {
  void callParent() { this->callBase(); }
  void publicMethod() {}
};

int main() {
  Derived d;
  d.callParent();
  d.callBase() // <- illegal
  return 0;
 }

Problem

The following code doesn't work, as you can't `static_cast` from private base class. Replacing the cast with a C-style cast works (although I originally thought this would invoke undefined behaviour apparently it does not, see this answer), but is rather ugly as it also allows you to bypass const-checking, etc. The other approach would be to make CRTPBase a friend, but that would expose all of Derived's private members. Is there another way of writing this without using a C-style cast and without making CRTPBase a friend? ``` template<typename T> struct CRTPBase { void callBase() { T * derived = static_cast<T*>(this); derived->publicMethod(); } }; struct Derived : private CRTPBase<Derived> { void callParent() { this->callBase(); } void publicMethod() {} }; int main() { Derived d; d.callParent(); return 0; } ```

Original source

Related problems