DarthRubik
DarthRubik

Reputation: 3975

Weird inheritance pattern

Suppose I have a base class like this:

class Abstract {
  public:
    /* This type should be the deriver of this class */ 
    virtual DerivedType foo(void) = 0;
};

And I want DerivedType to be different depending on who derives from this class. In fact I want DerivedType to be the type that Derives from Abstract.

I realize that I could do something like this:

template<typename der_t>
class Abstract {
  public:
    virtual der_t foo(void) = 0;
};

And then it should be used like this:

class Derived : public virtual Abstract<Derived> { };

Unfortunately there is no way to force someone to pass in the right type in the template. That is someone could do this:

class Derived : public virtual Abstract<int> { };

So is there any better way to do this, or is there a way to force someone to pass in the right parameter?

Upvotes: 2

Views: 90

Answers (1)

Quentin
Quentin

Reputation: 63124

The usual trick for CRTP's is to have a private constructor that only the passed-in class can access via a friend directive:

template <class Derived>
struct Crtp {

private:
    friend Derived;

    Crtp() = default;
};

It isn't perfect, but guards against errors.

Note : static_asserting is not a practical solution, because at the time Crtp is instantiated Derived is still incomplete, and can't be checked for base classes.

Upvotes: 2

Related Questions