2010-10-21 74 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)); 
} 
相關問題