选择要从中派生的 CRTP 基类
Selecting which CRTP base class to derive from
假设我有以下非常简单的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)和动态(虚拟)版本的最简单方法是什么,否则实现是相同的?
最简单的方法可能就是添加"class D"作为VirtualBase的未使用模板参数,使其符合相同的接口。
如果无法更改 VirtualBase,可以使用中间模板:
template <class D, class T> class VirtualBaseWrapper : public VirtualBase<T>{}
相关文章:
- CRTP 与基类向量
- CRTP 如何使派生类具有基类的容器
- 如何在CRTP实现中传递基类指针
- 使用CRTP将基类的子类传递给构造函数
- C++使用 CRTP 模板模板基类中的构造函数
- 从具有泛型返回类型的 crtp 基类调用派生类中的函数
- 如何使用 CRTP 创建具有基类的可选模板参数
- CRTP - 是否可以创建一个抽象基类?
- 使用 'this' 作为指向 CRTP 基类中派生类的指针
- 类型特征检查 CRTP 派生,在基类中,问题是未定义的类型
- CRTP 静态多态性:是否可以用模拟替换基类
- 为什么CRTP(奇怪的递归模板模式)试图选择另一个私有基类的另一个同名函数
- CRTP:基于派生类内容的基类启用方法
- CRTP-从基类中检查派生类是否满足要求
- CRTP层次结构类的非模板基类
- C++泛型编程 CRTP 基类继承自派生类型提供的类
- 延迟 crtp 基类中的成员函数实例化
- 检测 CRTP 基类的同级
- 通过CRTP基类覆盖虚函数
- 选择要从中派生的 CRTP 基类