做网站vpn多大内存,外贸行业网站推广,粮油移动端网页设计素材,旅游网站建设策划书范文如果一个模版看起来很头痛#xff0c;那么大概率这种模版是用来炫技#xff0c;没啥用的#xff0c;但是CRTP这个模版#xff0c;虽然看起来头大#xff0c;但是却经常被端上桌~
奇异递归模板模式#xff08;Curiously Recurring Template Pattern, CRTP#xff09;是一…如果一个模版看起来很头痛那么大概率这种模版是用来炫技没啥用的但是CRTP这个模版虽然看起来头大但是却经常被端上桌~
奇异递归模板模式Curiously Recurring Template Pattern, CRTP是一种 C 模板编程技巧用于实现静态多态。这种模式利用模板递归来允许一个类继承自一个模板类其中模板参数是该类自身。这种模式可以用于各种用途包括实现类型安全的单例模式、静态接口和性能优化。
CRTP基本概念
在 CRTP 模式中一个类 Derived 继承自一个模板类 Base这个模板类 Base 的模板参数是 Derived 自身。这样做的好处是允许在编译时确定 Derived 类型的信息从而在不需要运行时多态的情况下实现多态行为。以下是 CRTP 的基本示例展示了如何使用 CRTP 模式实现一个简单的静态接口
#include iostream
using namespace std;template typename Child
struct Base
{
void interface()
{static_castChild*(this)-implementation();
}
};struct Derived : BaseDerived
{
void implementation()
{cout Derived implementation\n;
}
};int main()
{Derived d;d.interface(); // Prints Derived implementationreturn 0;
}
CRPT模板展开
遇到CRPT不要慌一慌忘光光为了认识这种代码的本质我们不妨用Insights将其展开 C Insights
#include iostream
using namespace std;templatetypename Child
struct Base
{inline void interface(){static_castChild *(this)-implementation();}};/* First instantiated from: insights.cpp:13 */
#ifdef INSIGHTS_USE_TEMPLATE
template
struct BaseDerived
{inline void interface(){static_castDerived *(this)-implementation();}// inline constexpr Base() noexcept default;
};#endifstruct Derived : public BaseDerived
{inline void implementation(){std::operator(std::cerr, Derived implementation\n);}// inline constexpr Derived() noexcept default;
};int main()
{Derived d;static_castBaseDerived(d).interface();return 0;
} 可以发现展开的代码平平无奇一目了然。
Base 类是一个模板类它接受一个 Derived 类型作为模板参数。Derived 类继承自 BaseDerived从而在 Base 中能够静态地调用 Derived 类中的方法。
另一个CRPT实例
以下是一个稍微复杂一点使用 CRTP 实现策略模式的例子 #include iostream// CRTP 基类
template typename Derived
class Strategy {
public:
void execute() {// 调用 Derived 类中的实现static_castDerived*(this)-perform();
}
};// 具体策略 1
class ConcreteStrategy1 : public StrategyConcreteStrategy1 {
public:
void perform() {std::cout ConcreteStrategy1 implementation std::endl;
}
};// 具体策略 2
class ConcreteStrategy2 : public StrategyConcreteStrategy2 {
public:
void perform() {std::cout ConcreteStrategy2 implementation std::endl;
}
};int main() {ConcreteStrategy1 s1;ConcreteStrategy2 s2;s1.execute(); // 输出 ConcreteStrategy1 implementations2.execute(); // 输出 ConcreteStrategy2 implementationreturn 0;
}
在这个示例中Strategy 是 CRTP 基类它定义了一个 execute 方法该方法调用派生类的 perform 方法。具体策略类 ConcreteStrategy1 和 ConcreteStrategy2 实现了不同的 perform 方法。这样Strategy 基类就能够静态地调用不同的策略实现。
总结
看到CRPT第一眼应该想到这玩意没什么特别的就是为了实现静态多态的。
静态体现在哪儿都是模版函数在编译期都已经展开函数调用是写死的多态体现在哪儿调佣基类的公用接口最后会执行子类的具体实现这一点和虚函数多态有点相似但这种多态是静态的。
所以CRPT就这点东西。