以下是CRTP用于定义自定义集合类型的基本用法:
template <class __B>
struct A
{
typedef std::vector<__B> collection_type;
};
struct B: public A<B>
{
collection_type X;
};
用于模板
template <typename __T>
struct C: public A<C<__T>>
{
// collection_type X; <--- this does not compile
typename A<C<__T>>::collection_type X;
};
为什么“typename ... ::”部分需要C而不是B?
答案 0 :(得分:3)
struct B
是一个具体的类,而不是模板,它的定义不依赖于任何参数。因此,当编译器从A<B>
继承它时,它会从模板A<B>
实例化类A
,在其中看到collection_type
的定义并且很高兴。
struct C
是一个模板,因此A<C<__T>>
取决于参数__T
。 A
可以是专用的,因此编译器不知道collection_type
实际上是什么,或者即使它存在与否。因此,我们必须告诉编译器在哪里查找collection_type
(所以,A<C<__T>>::collection_type
),并且它是一个类型(所以typename A<C<__T>>::collection_type
)。