我想要做:
template <class Derived=BattleData>
class BattleData : public BattleCommandManager<Derived> {
};
但是显然
BattleData
没有声明,所以我尝试了一个前向声明:template <class T> class BattleData;
template <class Derived=BattleData>
class BattleData : public BattleCommandManager<Derived> {
};
但后来我明白了
我真的看不到解决方案!
编辑:
我这样做的原因是因为我希望能够直接将
BattleData
用作class
,但是我也希望能够对其进行子类化,在这种情况下,我必须将派生的class
指定为第二个template
参数。例如,假设我的
BattleData
类的主体是:template <class Derived> class BattleData: public BaseClass<Derived> {
void foo1(){};
void foo2(){};
void foo3(){};
}
我有一个子类
template class SubBattleData: public BattleData<SubBattleData> {
void foo1(){};
}
在某些情况下,我仍然希望能够编写如下代码:
BattleData *x = new BattleData(...);
如果不能使用默认参数,我什至无法执行以下操作:
BattleData<BattleData> *x = new BattleData<BattleData>(...);
一方面,在BattleData类中未对功能进行虚拟化的原因是没有虚拟功能的好处。另一个对我不起作用的原因是,父CRTP类中的一个仅在函数以派生类型存在时才调用函数(使用
decltype(Derived::function)
和enable-if-like结构),否则返回默认行为。由于可能存在大量具有特定设计模式的功能(例如,CRTP仅在派生类指定了相应功能的情况下读取具有许多不同情况的协议(protocol)并以特殊方式处理情况,否则,无需处理即可直接将其转移)。因此,这些函数可以出现在
SubBattleData
中,而不是BattleData
中,但是如果实例化这两个类,它们都可以正常工作,但无法实例化BattleData
。 最佳答案
您应该能够比以上更自然地完成原始设计目标。您不能明确地使用实际的Derived类型名称作为默认名称,因为您真正想写的是以下内容:
template <class Derived=BattleData <BattleData <BattleData <...>>>
class BattleData : public BattleCommandManager<Derived> {
};
你明白了。相反,只需使用像void这样的占位符:
template <typename T = void>
class BattleData : public BattleCommandManager <
typename std::conditional <
std::is_same <T, void>::value,
BattleData <void>,
T
>::type>
{
};
免责声明:我没有编译以上内容。
关于c++ - 将CRTP与多个模板参数一起使用时,如何声明模板默认值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7501235/