“奇怪的循环模板模式”的实际应用

什么是“ 奇怪的循环模板模式 ”的一些实际用途? 通常显示的“ 计数class ”例子对我来说不是一个令人信服的例子。

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

这对于mixin (我指的是从inheritance的类来提供function)也特别有用,它们本身需要知道它们在哪种types上运行(因此需要是模板)。

Effective C ++中 ,Scott Meyers提供了一个类模板NewHandlerSupport <T>。 这包含一个静态方法来覆盖特定类的新处理程序(与std :: set_new_handler对默认运算符new相同),以及使用处理程序的operator new。 为了提供一个per-type处理程序,父类需要知道它正在处理什么types,所以它需要是一个类模板。 模板参数是子类。

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

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

Meyers认为CRTP可能被认为是“为我而做”。 我会说这是一般的情况下,任何混音,CRTP适用于你需要一个混音模板,而不是一个混音类。

如果考虑到传递给超类的子types仅在方法扩展时才需要,那么CRTP就不那么好奇了。 那么所有的types都被定义了。 您只需要将模式导入超类的符号子types,但它只是一个前向声明 – 就所有超类而言,所有正式的模板参数types都是定义的。

我们使用一种有些修改的forms,将特性types结构中的子类传递给超类,以使超类能够返回派生types的对象。 该应用程序是一个用于几何微积分(点,向量,行,框)的库,其中所有通用function都在超类中实现,而子类只定义特定types:CFltPointinheritance自TGenPoint。 在TGenPoint之前也存在CFltPoint,所以子类化是重构这个的一种自然的方式。

一般来说,它被用于类似多态的模式,在那里你不需要能够在运行时select派生类,只能在编译时。 这可以节省运行时虚拟函数调用的开销。

对于一个真实世界的图书馆使用CRTP,看看ATL和WTL(wtl.sf.net)。 它被广泛用于编译时多态性。

感觉有点像Cmacros:利用这个macros不是在定义的时候编译的,而是在使用的时候编译的。

#define CALL_THE_RIGHT_FOO foo() 

文件 – 答:

 static void foo() { // do file A thing } ... CALL_THE_RIGHT_FOO ... 

文件 – 答:

 static void foo() { // do file B thing } ... CALL_THE_RIGHT_FOO ... 

您所描述的模板使用模式允许我们在父模板中“调用正确的foo”,推迟正确的foo的定义,直到模板被实例化。 除了在这种情况下,基于Parent中的T值,ClassA :: foo和ClassB :: foo之间的区别。