我希望有一个在编译时选择的具有多种可能实现的接口。我看到 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
不幸的是,在这两种情况下,编译器都不会捕获它,除非我真的尝试使用它。Strategy 变体对我来说似乎更好,因为它避免了丑陋static_cast
,并且使用组合而不是继承。还有什么 CRTP 允许的,策略不允许的吗?为什么主要使用 CRTP 代替?