我有一个模板类
template <class T>
class myClass
{
public:
/* functions */
private:
typename T::Indices myIndices;
};
现在在我的主代码中,我想根据条件实例化模板类。喜欢:
myFunc( int operation)
{
switch (operation) {
case 0:
// Instantiate myClass with <A>
auto_ptr < myClass <A> > ptr = new myClass<A> ();
case 1:
// Instantiate myClass with <B>
auto_ptr < myClass <B> > ptr = new myClass<B> ();
case 2:
// Instantiate myClass with <C>
....
}
// Use ptr here..
}
现在这种方法的问题是auto_ptr<>
会在switch{}
结束时死亡。
我不能在函数的开头声明它,因为我不知道之前将被实例化的类型。
我知道我正在尝试在编译时(使用模板)实现运行时的事情,但仍然想知道是否有更好的方法来执行此操作。
答案 0 :(得分:7)
创建基类
class Base {
protected:
virtual ~Base() {}
//... functions
};
template <class T> class myClass : Base {
//...
};
myFunc( int operation){
shared_ptr < Base > ptr;
switch (operation) {
case 0:
// Instantiate myClass with <A>
ptr.reset ( new myClass<A> () );
case 1:
// Instantiate myClass with <B>
ptr.reset ( new myClass<B> () ) ;
case 2:
// Instantiate myClass with <C> ....
}
// Use ptr here..
}
答案 1 :(得分:4)
您可以为myClass
引入一个公共基础,并将其用作auto_ptr
的参数。只是不要忘记声明该公共基础的析构函数是虚拟的。
答案 2 :(得分:2)
Boost.Variant应该可以做到这一点。
myFunc( int operation)
{
boost::variant< myclass<A>, myclass<B> > obj;
switch (operation) {
case 0:
// Instantiate myClass with <A>
obj = myClass<A> ();
case 1:
// Instantiate myClass with <B>
obj = myClass<B> ();
case 2:
// Instantiate myClass with <C>
....
}
// Use object here..
}
使用该对象有点不同,因为类型是动态确定的。 apply_visitor技术绝对是最佳选择;请参阅tutorial了解如何使用它。
答案 3 :(得分:1)
您可以添加间接级别以获得所需内容。您可以避免使用虚拟方法的基类并执行任何其他特殊操作。
例如:
template <class T>
class MyClass
{
public:
/* functions */
private:
typename T::Indices myIndices;
};
template<typename T>
static void doit()
{
MyClass<T> t;
// Use t here.
}
void myfunc(int op)
{
switch (op) {
case 0: return doit<A>();
case 1: return doit<B>();
// ...
}
}
答案 4 :(得分:0)
低技术解决方案。使用具有所需范围的常规指针。