什么是奇怪的重复模板模式(CRTP)? [英] What is the curiously recurring template pattern (CRTP)?
问题描述
任何人都可以用代码示例为 CRTP
提供一个很好的解释?
请不要请我参考一本书,我已经做了有书和引用他们,但我通常找到你们提出的解释/例子,在理解概念和许多其他重要的微妙的东西,一个概念更合适和实用。
Can anyone please provide a good explanation for CRTP
with a code example?
Please do not ask me to refer a book, I already do have the books and refer them but I usually find the explanations/examples that you guys come up with at SO much more suitable and practical in understanding the concept and lot of other important subtle things that go with a concept.
推荐答案
简而言之,CRTP是A类有一个基类,它是A类本身的模板专用化。例如
In short, CRTP is when a class A has a base class which is a template specialization for the class A itself. E.g.
template <class T> class X{...};
class A : public X<A> {...};
这是奇怪的重现,不是吗? :)
It is curiously recurring, isn't it? :)
现在,这给了你什么?这实际上给了X模板作为其专门化的基类的能力。
Now, what does this give you? This actually gives the X template the ability to be a base class for its specializations.
例如,您可以像这样创建一个通用单例类(简化版本)。
For example, you could make a generic singleton class (simplified version) like this
template <class ActualClass>
class Singleton
{
public:
static ActualClass& GetInstance()
{
if(p == nullptr)
p = new ActualClass;
return *p;
}
protected:
static Actualclass* p;
private:
Singleton(){}
Singleton(Singleton const &);
Singleton& operator = (Singleton const &);
};
template <class T>
T* Singleton<T>::p = nullptr;
现在,为了使一个任意类A成为单例,你应该这样做
Now, in order to make an arbitrary class A a singleton you should do this
class A: public Singleton<A>
{
//Rest of functionality
};
所以你看到了?单例模板假定其对任何类型X的专门化将继承自 singleton< X>
,并且因此将具有所有其(公共的,受保护的)成员可访问,包括 GetInstance
!还有CRTP的其他有用的用途。例如,如果你想计算你的类当前存在的所有实例,但是想要将这个逻辑封装在一个单独的模板中(对于一个具体的类,思想是非常简单的 - 有一个静态变量,在ctors中递增,在dtors中递减)。尝试做一个锻炼!
So you see? The singleton template assumes that its specialization for any type X will be inherited from singleton<X>
and thus will have all its(public, protected) members accessible, including the GetInstance
! There are other useful uses of CRTP. For example, if you want to count all instances that currently exist for your class, but want to encapsulate this logic in a separate template (the idea for a concrete class is quite simple - have a static variable, increment in ctors, decrement in dtors). Try to do it as an excercise!
另一个有用的例子,boost(我不知道他们是如何实现的,但CRTP也会)。
想象一下,你想提供只有operator<
Yet another useful example, for boost(I am not sure how they have implemented it, but CRTP will do too). Imagine you want to provide only operator < for your classes but automatically operator == for them!
你可以这样做:
template<class Derived>
class Equality
{
};
template <class Derived>
bool operator == (Equality<Derived> const& op1, Equality<Derived> const & op2)
{
Derived const& d1 = static_cast<Derived const&>(op1);//you assume this works
//because you know that the dynamic type will actually be your template parameter.
//wonderful, isnit it?
Derived const& d2 = static_cast<Derived const&>(op2);
return !(d1 < d2) && !(d2 < d1);//assuming derived has operator <
}
现在可以像这样使用
struct Apple:public Equality<Apple>
{
int size;
};
bool operator < (Apple const & a1, Apple const& a2)
{
return a1.size < a2.size;
}
现在,你没有为apple提供明确的operator ==但你有它!您可以写
now, you haven't provided explicitly operator == for apple? But you have it! You can write
int main()
{
Apple a1;
Apple a2;
a1.size = 10;
a2.size = 10;
if(a1 == a2) //the compiler won't complain!
{
}
}
如果你只是为苹果编写operator ==,但是想象平等模板不仅会提供==,但是>,> =,< =等。你可以使用这些定义 multiple 类,重用代码!
This could seem that you would write less if you just wrote operator == for Apple, but imagine that the Equality template would provide not only == but >, >=, <= etc. And you could use these definitions for multiple classes, reusing the code!
CRTP是一件奇妙的事情:) HTH
CRTP is a wonderful thing :) HTH
这篇关于什么是奇怪的重复模板模式(CRTP)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!