"Curiously Recurring Template Pattern"的实际用途



"奇怪的重复模板模式"有哪些实际用途? 通常显示的"计数类"示例对我来说不是一个令人信服的例子。

模拟动态绑定。避免虚拟函数调用的成本,同时保留一些分层优势,对于可以在我目前正在从事的项目中完成的子系统来说是一个巨大的胜利。

它对于 mixins(我的意思是你从中继承以提供功能的类)也特别有用,它们本身需要知道它们在什么类型上运行(因此需要是模板)。

Effective C++中,Scott Meyers 提供了一个类模板 NewHandlerSupport 作为示例。它包含一个静态方法,用于重写特定类的新处理程序(与 std::set_new_handler 对默认运算符 new 所做的方式相同),以及使用该处理程序的运算符 new。为了提供每类型处理程序,父类需要知道它正在操作的类型,因此它需要是一个类模板。模板参数是子类。

如果没有 CRTP,您就无法真正做到这一点,因为您需要单独实例化 NewHandlerSupport 模板,并使用单独的静态数据成员来存储当前new_handler,每个使用它的类。

显然,整个示例非常非线程安全,但它说明了这一点。

迈耶斯认为,CRTP可能被认为是"为我做"。我想说的是,任何 mixin 通常都是这种情况,CRTP 适用于您需要 mixin 模板而不仅仅是 mixin 类的情况。

如果您认为传递给超类的子类类型仅在方法扩展时需要,则 CRTP 的好奇心就会少得多。因此,定义了所有类型。您只需要将符号子类类型导入超类的模式,但就超类而言,它只是一个前向声明 - 因为所有正式模板参数类型都是根据定义。

我们以某种修改的形式使用,将 traits 类型结构中的子类传递给超类,以使超类可以返回派生类型的对象。该应用程序是一个用于几何微积分(点,向量,线,框)的库,其中所有通用功能都在超类中实现,子类只定义一个特定的类型:CFltPoint继承自TGenPoint。此外,CFltPoint 在 TGenPoint 之前就已经存在,因此子类化是重构它的自然方式。

通常,

它用于类似多态的模式,在这些模式中,您不需要能够在运行时选择派生类,只需在编译时。这可以节省运行时虚拟函数调用的开销。

有关 CRTP 的实际库使用,请查看 ATL 和 WTL (wtl.sf.net)。它在那里广泛用于编译时多态性。

相关内容

  • 没有找到相关文章

最新更新