2010-10-21 80 views
0

我正在为游戏世界中的某些对象创建一个统计编辑器。我没有为每种对象类型提供多个编辑菜单,而只是有一个菜单,并且传入一个stat-edit-objects的列表/矢量,其中包含一个指向正在编辑的统计数据的指针,以及执行该工作的函数。如何使用CLASSNAME <typename>(参数)自动化模板类型名称说明;

struct StatEditObjPureBase 
{ 
    std::vector<std::string> reps; 
    std::string name; 
    std::basic_string<int> value; 
    const iWindow* win; 
    Editor* pE; 

    StatEditObjPureBase(iWindow& rIW, Editor& rE) : win(&rIW), pE(&rE) {} 

    virtual ~StatEditObjPureBase() = 0; 
    virtual StatEditObjPureBase* clone() = 0; 
    virtual void set() = 0; 
    virtual void dec() = 0; 
    virtual void inc() = 0; 
    virtual void update() = 0; 
}; 

struct StatEditObjWrap 
{ 
    StatEditObjPureBase* base; 

    StatEditObjWrap(StatEditObjPureBase* p) : base(p) {} 
    StatEditObjWrap(const StatEditObjWrap& that) { base = that.base->clone(); } 
    ~StatEditObjWrap() { delete base; } 
}; 

template<class T> struct StatEditObj_INT : StatEditObjPureBase 
{ 
    T* pMain; 

    StatEditObj_INT(T* p, iWindow& rIW, Editor& rE) : StatEditObjPureBase(rIW, rE), pMain(p) {} 
    StatEditObj_INT* clone() { return new StatEditObj_INT(*this); } 
    void set(); 
    void dec(){--(*pMain);} 
    void inc(){++(*pMain);} 
    void update(); 
}; 

template<class T> void StatEditObj_INT<T>::set() 
{ 
    *pMain = input_getInt(win->box_input_y, win->box_input_x, win->box_input_range, win->box_input_fg, win->box_input_bg); 
} 

template<class T> void StatEditObj_INT<T>::update() 
{ 
    staticStatEditObj_intUpdate(*pMain, value, reps); 
} 

我的主要问题是不得不指出其指针存储在模板派生类中的变量的类型。下面的代码是一个小例子,但是你可以认为,将有数百个这样的统计编辑对象的条目:

void Editor::statEditObjectTemplate(ObjectTemplate& r) 
{ 
    std::vector<iWindowEntry> temp; 
    iWindow iw(17, 60, temp); 

    std::vector<StatEditObjWrap> stats; 

    { StatEditObjWrap stat(new StatEditObj_INT<unsigned short>(&r.glyph, iw, *this)); stats.push_back(stat); } 
    { StatEditObjWrap stat(new StatEditObj_INT<unsigned int>(&r.mappedFcolour, iw, *this)); stats.push_back(stat); } 
    { StatEditObjWrap stat(new StatEditObj_INT<unsigned int>(&r.mappedBcolour, iw, *this)); stats.push_back(stat); } 

    statEditor(stats, iw); 
} 

有没有办法来对

new StatEditObj_INT<type>(&r.variable, iw, *this) 

自动传递的模板类型名?

(注:类型是StatEditObj_INT的构造函数的第一个参数)

回答

2

是的,你可以使用一个工厂函数:

// Note: Callee takes ownership of returned pointer 
// (Alternatively, you should consider using a smart pointer like shared_ptr) 
template <typename T> 
StatEditObj_INT<T>* MakeNew_StatEditObj_INT(T* p, iWindow& rIW, Editor& rE) 
{ 
    return new StatEditObj_INT<T>(p, rIW, rE); 
} 

然后,你必须:

stats.push_back(MakeNew_StatEditObj_INT(&r.glyph, iw, *this)); 
stats.push_back(MakeNew_StatEditObj_INT(&r.mappedFcolour, iw, *this)); 
stats.push_back(MakeNew_StatEditObj_INT(&r.mappedBcolour, iw, *this)); 

该作品因为当你使用一个函数模板时,编译器可以从函数参数中推导出模板参数(很明显,它不能这样做,就像你有一个模板参数仪表未在功能参数列表中表示,或仅在未推导的上下文中表示)。在处理类模板时,这是一个常见的习惯用法。

+0

在示例代码OP了,不能他只是省略类型,让编译器确定它(你多大如何在这里做什么用'MakeNew_StatEditObj_INT' – JoshD 2010-10-21 21:58:58

+0

@JoshD吗?不,因为你必须在新表达式中指定类型名称;编译器无法从构造函数调用中推导出类模板参数 – 2010-10-21 22:02:12

+0

谢谢,我不知道这一点。 – JoshD 2010-10-21 22:02:43

1

在非模板类中使用模板成员函数。

struct StatEditObjWrap 
{ 
    template <typename T> 
    static StatEditObjWrap create(T* p, iWindow& rIW, Editor& rE); 

    //... 
} 

template <typename T> 
StatEditObjWrap StatEditObjWrap::create<T>(T* p, iWindow& rIW, Editor& rE) { 
    return StatEditObjWrap(new StatEditObj_INT<T>(p, rIW, rE)); 
} 

{ 
    vector<StatEditObjWrap> stats; 
    stats.push_back(StatEditObjWrap::create(&r.glyph, iW, *this)); 
} 
相关问题