I want to have an interface with multiple possible implementations, selected at compile-time. I saw that CRTP is the idiom of choice for implementing this. Why is that? An alternative is the Strategy pattern, but I see no mention of this technique anywhere:
template <class Impl>
class StrategyInterface
{
public:
void Interface() { impl.Implementation(); }
void BrokenInterface() { impl.BrokenImplementation(); }
private:
Impl impl;
};
class StrategyImplementation
{
public:
void Implementation() {}
};
template <class Impl>
class CrtpInterface
{
public:
void Interface() { static_cast<Impl*>(this)->Implementation(); }
void BrokenInterface() { static_cast<Impl*>(this)->BrokenImplementation(); }
};
class CrtpImplementation : public CrtpInterface<CrtpImplementation>
{
public:
void Implementation() {}
};
StrategyInterface<StrategyImplementation> str;
CrtpImplementation crtp;
BrokenInterface
is not caught by the compiler in either case, unfortunately, unless I actually try to use it. The Strategy variant seems better to me, as it avoids an ugly static_cast
and it uses composition instead of inheritance. Is there anything else CRTP allows, that Strategy does not? Why is CRTP predominantly used instead?
The usual implementation of the strategy pattern is exactly like your CRTP implementation. A base class defines some kind of algorithm, letting out some parts that are implemented in deriving classes.
So the CRTP implements the strategy pattern. Your StrategyInterface simply delegates the implementation of the details and is not an implementation of the strategy pattern.
While both of your implementations achieve the same effect, I would prefer the CRTP because it would take advantage of possible empty base class optimizations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With