2010-06-23 44 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; 
}