Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Strategy and CRTP for static polymorphism?

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?

like image 564
Dan Nestor Avatar asked Jan 11 '14 13:01

Dan Nestor


1 Answers

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.

like image 108
Torsten Robitzki Avatar answered Oct 16 '22 13:10

Torsten Robitzki