【问题标题】:Selecting which CRTP base class to derive from选择从哪个 CRTP 基类派生
【发布时间】:2013-02-03 10:30:30
【问题描述】:

假设我有以下非常简单的 CRTP 基类:

template< class D, class T >
struct Base
{

    T foo() 
    {   
        return static_cast< D* >(this)->foo_i();
    }

};

还有一些派生类。一切正常,但有一个问题:有 一个 特殊情况(或者可能是几个)我会真的,真的喜欢两个类具有运行时多态行为(需要将它们放入容器中)。换句话说,我希望一些派生的 CRTP 类也有虚拟版本。所以,我想出了以下课程:

template< class T >
struct VirtualBase : public Base< VirtualBase< T >, T >
{

    virtual T foo_i() = 0;

};

现在,我需要运行时多态性,我只是从这个类派生。假设我希望我的派生类DerivedB 有一个虚拟版本。原版 DerivedB 如下所示:

template< class T >
struct DerivedB : public Base< DerivedB< T >, T >
{

    T foo_i() 
    { 
        std::cout << "I'm special!\n";
        return T(); 
    }

};

我想要做的基本上是向这个类添加一个额外的模板参数,以便我可以在编译时选择是从 Base 派生(如果我想要模拟“动态”绑定)还是 VirtualBase(如果我想要真正的动态绑定)。类似于以下伪 C++:

template< class B, class T >
struct DerivedB : public B< DerivedB< T >, T >
{

    T foo_i() 
    { 
        std::cout << "I'm special!\n";
        return T(); 
    }

};

因此,对于普通 CRTP,将 Base 作为 B 传递,对于虚拟类,将 VirtualBase 作为 B 传递。当然,问题在于它们采用不同数量的参数(Base 需要派生类的类型),我无法提出可行的解决方案。

那么,如何在编译时选择基类?或者,如果这太复杂/不可能,那么拥有静态(CRTP)和动态(虚拟)版本的类的最简单方法是什么,否则实现是相同的?

【问题讨论】:

    标签: c++ templates crtp static-polymorphism


    【解决方案1】:

    最简单的方法大概就是在VirtualBase的一个未使用的模板参数中加入“class D”,使其符合相同的接口。

    如果您无法更改 VirtualBase,您可以使用中间模板:

    template <class D, class T> class VirtualBaseWrapper : public VirtualBase<T>{}
    

    【讨论】:

      猜你喜欢
      • 2021-10-25
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多