为什么在通过CRTP访问派生类中的typedef时会出错?

时间:2012-08-09 12:23:02

标签: c++ crtp

我无法理解为什么下面的代码无法编译 - 有人可以解释一下吗?

如何从基类访问派生类中的typedef?

template<class Derived>
struct Test
{
    template<class T>
    typename Derived::value_type foo(T);
};

struct Derived : public Test<Derived>
{
    typedef int value_type;
};

2 个答案:

答案 0 :(得分:6)

在声明Derived时,Derived还不是一个完整的类型 - 你刚刚开始声明它!因此,在专门化Test<Derived>中,模板参数是一个不完整的类型,因此您不能引用嵌套名称,例如Derived::value_type - 这是循环逻辑。

您可以通过将返回类型设置为单独的参数来解决问题:

template <typename T, typename R> struct Test
{
    template <typename U> R foo(U);
};

template <typename R>
struct BasicDerived : public Test<BasicDerived, R>
{
    typedef R value_type;
};

typedef BasicDerived<int> Derived;

答案 1 :(得分:5)

您无法直接在基类中访问typedef或模板类的成员,因为此时它不是完整类型。允许这样会导致循环行为:

template<class Derived>
struct Test
{
    typedef typename Derived::value_type foo;
};

struct Derived : public Test<Derived>
{
    typedef Test<Derived>::foo value_type;
};

但是,您可以在方法中引用模板类的成员,因为它们直到稍后才会实例化:

template<class Derived>
struct Test
{
    void foo() { typename Derived::value_type bar; }
};

struct Derived : public Test<Derived>
{
    typedef int value_type;
};

或者,根据您的尝试,您可以将typedef作为附加模板参数传递:

template<typename value_type, class Derived>
struct Test
{
    template<class T>
    value_type foo(T);
};

struct Derived : public Test<int, Derived>
{
    typedef int value_type;
};