有没有办法自动为所有派生类执行此操作,我不必为所有嵌套类创建函数applyPack。
这是我的代码:
/** every class has registered id with this function */
template<typename T>
uint getID() {
static uint id = registerClass<T>();
return id;
}
class TemplatesPack {
public:
template<typename T>
typename T::Template get();
};
class Object {
public:
virtual void applyPack(TemplatesPack *p) { this->setTemplate(p->get<Object>()); };
};
class Object2: public Object {
public:
void applyPack(TemplatesPack *p) { this->setTemplate(p->get<Object2>()); };
};
class Object3: public Object {
public:
void applyPack(TemplatesPack *p) { this->setTemplate(p->get<Object3>()); };
};
class Object4: public Object2 {
public:
void applyPack(TemplatesPack *p) { this->setTemplate(p->get<Object4>()); };
};
我已经阅读了有关类型特征的内容,但我不想让类对象模板化。可以用c ++完成,并在TemplatesPack类或c ++ 0x中模板化一些函数吗?小号
答案 0 :(得分:5)
编辑:
改变了答案,使对象不受影响。
template<class T>
class Base<T> : public Object
{
public:
virtual void applyPack(TemplatePack *p) { this->setTemplate(p->get<T>()); };
};
class Object2 : public Base<Object2>
{
// ...
};
编辑:对于Object4
的情况,可能以下内容会有所帮助:
template<class S, class D>
class Base<S, D> : public S
{
public:
virtual void applyPack(TemplatePack *p) { this->setTemplate(p->get<D>()); };
};
class Object2 : public Base<Object, Object2> { /* ... */ };
class Object3 : public Base<Object, Object3> { /* ... */ };
class Object4 : public Base<Object2, Object4> { /* ... */ };
答案 1 :(得分:1)
如果您不想模板Base
template<typename Derived, typename Base = void>
struct applyer : virtual applyer<Base, typename Base::base_type> {
virtual void applyPack(TemplatesPack *p) {
dynamic_cast<Derived*>(this)->setTemplate(p->get<Derived>());
};
typedef Base base_type;
};
template<typename Derived>
struct applyer<Derived, void> {
virtual void applyPack(TemplatesPack *p) {
dynamic_cast<Derived*>(this)->setTemplate(p->get<Derived>());
};
};
现在你可以按照以下方式进行操作
class Object : virtual public applyer<Object> {
};
class Object2: public Object, virtual public applyer<Object2, Object> {
};
class Object3: public Object, virtual public applyer<Object3, Object> {
};
第二个参数分别是直接基类,如果没有则可以省略。例如,如果您从Object3
派生,则需要按照以下方式执行此操作
class Object3_1: public Object3, virtual public applyer<Object3_1, Object3> {
};