コンパイル時に選択される、複数の可能な実装を持つインターフェイスが必要です。CRTP がこれを実装するためのイディオムであることがわかりました。何故ですか?代替手段は戦略パターンですが、この手法についてはどこにも言及されていません。
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
残念ながら、実際に使用しようとしない限り、どちらの場合もコンパイラにキャッチされません。戦略バリアントは、醜いものを回避し、static_cast
継承の代わりに構成を使用するため、私には優れているようです。CRTP で許可されていて、ストラテジーでは許可されていないものは他にありますか? 代わりに CRTP が主に使用されるのはなぜですか?