使用CRTP和typedef的"继承"类型

Ken*_*han 5 c++ templates

以下代码无法编译.我收到一条错误消息:错误C2039:'Asub':不是'C'的成员

有人能帮助我理解这个吗?

试过VS2008和2010编译器.

template <class T>
class B
{
    typedef int Asub;

public:
 void DoSomething(typename T::Asub it)
 {

 }
};

class C : public B<C>
{
public:
 typedef int Asub;

};

class A
{
public:
 typedef int Asub;

};


int _tmain(int argc, _TCHAR* argv[])
{
 C theThing;
 theThing.DoSomething(C::Asub());

 return 0;
}
Run Code Online (Sandbox Code Playgroud)

Geo*_*che 8

你对这里的编译器有点不公平 - C在没有B<C>完全知道的情况下是不完整的,当处理时B<C>,C仍然是一个不完整的类型.comp.lang.c ++.moderatedcomp.lang.c ++上有类似的线程.

请注意,如果您通过将其移动到成员函数定义来延迟使用它,它会起作用,例如:

struct C : B<C> {
    void f() { typedef typename C::Asub Asub; }
};
Run Code Online (Sandbox Code Playgroud)

您可以通过明确向上传递类型来解决问题:

template<class T, class Asub> struct B { /* ... */ };
class C : B<C, int> { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

...或者如果你需要传递更多信息,可以将它们移动到某些特质课程:

template<class T, class Traits> struct B {
  void DoSomething(typename Traits::Asub it) {}
};

struct CTraits {
    typedef int Asub;
};

struct C : B<C, CTraits> {
    typedef CTraits::Asub Asub;    
};
Run Code Online (Sandbox Code Playgroud)