2012-11-19 57 views
0

在我的项目之一,我用同样的方法CRTP(从enable_crtp派生)在回答1浏览:How do I pass template parameters to a CRTP?如何处理CRTP的类层次?

不过,我有必要从派生类派生了。有没有什么办法让与了落回到刚才的static_cast this指针,但是通过使用来自启用CRTP基类的自()方法,这项工作?

#include "EnableCRTP.h" 

template<typename DERIVED> 
class BASE : public EnableCRTP<DERIVED> 
{ 
    friend DERIVED; 
public: 
    void startChain() 
    { 
     self()->chain(); 
    } 
}; 

template<typename DERIVED> 
class Derived1 : public BASE<Derived1<DERIVED> > 
{ 
public: 
    void chain() 
    { 
     std::cout << "Derived1" << std::endl; 

     //self()->chain2(); <- compile Error 
     static_cast<DERIVED*>(this)->chain2(); // <-Works 
    } 
}; 

class Derived2 : public Derived1<Derived2> 
{ 
public: 
    void chain2() 
    { 
     std::cout << "Derived2" << std::endl; 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Derived2 der;  
    der.startChain();  
    return 0; 
} 

回答

1

您可以将派生最多的类作为模板参数提供给CRTP基类,以便它可以访问其所有成员。取而代之的

template<typename DERIVED> 
class Derived1 : public BASE<Derived1<DERIVED> > 

用途:

template<typename DERIVED> 
class Derived1 : public BASE<DERIVED> 

也有你的代码的其他问题。例如,你不能直接调用self()像你这样,因为编译器不知道self是基类(这是依赖于模板参数)的成员。相反,调用this->self()。见this FAQ entry

0

做你想做什么,你只能通过CRTP传递最派生类。在这种情况下,你需要Derived1的定义更改为以下:

template<typename DERIVED> 
class Derived1 : public BASE<DERIVED> 
{ 
public: 
    void chain() 
    { 
     std::cout << "Derived1" << std::endl; 

     this->self()->chain2(); // should work now 
     //static_cast<DERIVED*>(this)->chain2(); // <-Works 
    } 
}; 

此外,使用CRTP与类层次结构时,它通常是更好地建立层次结构,使得类要么设计成可导出从(并因此是被传递派生类的模板),或是所述分层结构的叶,而不是衍生自。这些叶类不一定是模板。