【问题标题】:How to handle CRTP in a class hierarchy?如何在类层次结构中处理 CRTP?
【发布时间】:2012-11-07 08:44:40
【问题描述】:

在我的一个项目中,我使用与此处的答案 1 相同的 CRTP 方法(源自 enable_crtp):How do I pass template parameters to a CRTP?

但是我也需要从派生类派生。有什么方法可以使这项工作不回退到只是 static_cast this 指针,而是使用 Enable CRTP 基类中的 self() 方法?

#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;
}

【问题讨论】:

    标签: c++ templates crtp


    【解决方案1】:

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

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

    用途:

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

    您的代码还存在其他问题。例如,您不能像您一样直接调用self(),因为编译器不知道self 是基类的成员(依赖于模板参数)。相反,请致电this-&gt;self()。见this FAQ entry

    【讨论】:

      【解决方案2】:

      要做你想做的事,你只需要通过 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 时,通常最好设置层次结构,以便类设计为派生自(因此是传递 DERIVED 类的模板),或者是层次结构,而不是派生自。这些叶类根本不必是模板。

      【讨论】:

        猜你喜欢
        • 2011-10-17
        • 2022-01-12
        • 1970-01-01
        • 2020-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多