使用 CRTP 的模板中的继承类型

Inherited types in templates using CRTP

下面是 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;
};

为什么 C 需要 "typename ...::" 部分而 B 不需要?

struct B是具体的class,不是模板,它的定义不依赖于任何参数。因此,当编译器从 A<B> 继承它时,它从模板 A 实例化 class A<B>,在其中看到 collection_type 的定义并且很高兴。

struct C是模板,所以A<C<__T>>依赖于参数__TA 可以专门化,因此编译器不知道 collection_type 实际是什么,甚至不知道它是否存在。所以,我们必须告诉编译器在哪里寻找 collection_type(所以,A<C<__T>>::collection_type),并且它是一个类型(所以 typename A<C<__T>>::collection_type)。