2010-06-23 43 views
1

我有一個抽象類頂點代表一個n元組。頂點的元素可以是任何類型的:即,頂點的組件可以是int,int,float或類型的。因爲頂點可具有的尺寸,想到使類的任意數量的具有成分設定器像這樣:解決無法使功能模板變爲虛擬?

class vertex { 
    public: 
     template <class T> 
     virtual void setComp(int componentnumber, T value) = 0; 
}; 

當然,C++不允許虛擬功能模板。所以:我應該怎麼做?我也不知道我應該如何爲頂點寫一個getter。

謝謝。

+1

我舉了一個使用類型擦除的例子來達到預期的效果,作爲回答http://stackoverflow.com/questions/1277650/templatized-virtual-function/1278328 – AProgrammer 2010-06-23 15:04:32

回答

0

這是一個非常奇怪的面向對象和泛型編程的混合。我認爲你應該選擇一個或另一個。

使頂點類成爲模板定義'value'參數的基類並派生自定義類型處理程序類。

0

使用多態而不是模板。

或限制您想要傳遞的類型,並使重載。並增加維護成本。

實施這些解決方案將涉及到boost :: any或boost :: variant,以節省您一些時間。

0

Because the vertex can have an arbitrary number of dimensions - 西隧不能使它一個

template<size_t N> class vector { 

    private: 
    boost::any elems[N]; 
} 

然後以避免混合運行時多態性,並通過模板編譯時多態?或者如果它們的數量有限,則對任何可能的類型使用函數重載。

virtual void setComp(int, float) = 0; 
virtual void setComp(int, bool) = 0; 
+0

我記得有一個像這樣的設計,然後哭了爲什麼我不簡單地做成NA成員變量... – 2010-06-23 15:11:48

0

首先,我會問自己是否真的需要在運行時以多態方式訪問頂點對象。例如,如果你需要能夠擁有不同類型的頂點*對象列表(double,int等)並以多態的方式訪問它們。

在我看來,像頂點是編譯時多態的典型情況(即template <typename CoordinateType> class vertex;模板)。

+0

我甚至會去與一個簡單的數組或同等,但問題是關於虛擬模板,而不是這樣的設計是否好。 – 2010-06-23 15:09:50

2

好了,通常情況下,你應該有頂點類型作爲模板參數,因此它可以正確保存:

template<typename T, size_t NumAxes = 3> 
class vertex { 
    private: 
     T comp[NumAxes]; 
}; 

在這種情況下,沒有必要爲一個虛擬的方法,因爲你可以使用C++的類型轉換做的工作:

template<typename T, size_t NumAxes = 3> 
class vertex { 
public: 
    template <typename U> 
    void setComp(size_t index, U value) { comp[index] = static_cast<T>(value); } 
private: 
    T comp[NumAxes]; 
}; 

現在,如果你想,因爲你要子類可以用的東西亂七八糟它是虛擬的(如登錄值的每一個變化),你需要定義一個非模板功能:

template<typename T, size_t NumAxes = 3> 
class vertex { 
public: 
    template <typename U> 
    void setComp(size_t index, U value) 
    { _setComp(index, static_cast<T>(value)); } 
protected: 
    T comp[NumAxes]; 
    virtual void _setComp(size_t index, T value) 
    { comp[index] = value; } 
}; 

template<typename T, size_t NumAxes = 3> 
class logged_vertex: public vertex<T, NumAxes> { 
protected: 
    virtual void _setComp(size_t index, T value); 
}; 

template<typename T, size_t NumAxes = 3> 
void logged_vertex<T, NumAxes>::_setComp(size_t index, T value) 
{ cout << "Index " << index << " changed from " << comp[index]; 
    vertex<T, NumAxes>::_setComp(index, value); 
    cout << " to " << comp[index] << endl; 
}