gpt4 book ai didi

c++ - 使用带有多个模板参数的 CRTP 时如何声明模板默认值?

转载 作者:搜寻专家 更新时间:2023-10-31 00:45:06 24 4
gpt4 key购买 nike

我想做的事:

template <class Derived=BattleData>
class BattleData : public BattleCommandManager<Derived> {
};

但很明显 BattleData 没有声明,所以我尝试了前向声明:

template <class T> class BattleData;

template <class Derived=BattleData>
class BattleData : public BattleCommandManager<Derived> {
};

但后来我明白了

error: "wrong number of template parameter on the second line, with BattleData.

我真的找不到解决办法!

编辑:

我这样做的原因是因为我希望能够将 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像结构),否则回退到默认行为。由于可能有大量具有特定设计模式的函数(如 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com