在运行时有条件地实例化模板

发布于 2024-08-12 20:18:09 字数 861 浏览 4 评论 0原文

我有一个模板类


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{} 结束时死亡。 而且我不能在函数的开头声明它,因为我不知道预先实例化的类型。

我知道我正在尝试在编译时(使用模板)实现运行时的事情,但仍然想知道是否有更好的方法来做到这一点。

I have a template class


template <class T> 
class myClass
{
    public:
        /* functions */
    private:
        typename T::Indices myIndices;  
};
 

Now in my main code I want to instantiate the template class depending on a condition. Like :


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..
}

Now the problem with this approach is that the auto_ptr<> will die at the end of switch{}.
And I can't declare it at the beginning of the function, because I don't know the type that will be instantiated before-hand.

I know I'm trying to achieve a run-time thing at compile-time (using template), but still wanted to know if there is some better way to do this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

拍不死你 2024-08-19 20:18:09

创建一个基类

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..
}

Create a base class

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..
}
听不够的曲调 2024-08-19 20:18:09

您可以向 myClass 引入一个公共基础,并将其用作 auto_ptr 的参数。只是不要忘记将公共基类的析构函数声明为虚拟的。

You could introduce a common base to myClass and use that as the parameter to auto_ptr. Just don't forget to declare that common base's destructor virtual.

埋情葬爱 2024-08-19 20:18:09

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 技术绝对是最佳选择;请参阅教程了解如何使用它。

Boost.Variant should do the trick.

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..
}

Using the object is a little different because the type is dynamically determined. The apply_visitor technique is definitely the way to go; see the tutorial for how to use it.

赠我空喜 2024-08-19 20:18:09

您可以添加一定程度的间接性来获得您想要的东西。您可以避免使用具有虚拟方法的基类并执行任何其他特殊操作。

例如:

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>();
        // ...
     }
 }

You can add a level of indirection to get what you want. You can avoid a base class with virtual methods and doing any other special stuff.

For example:

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>();
        // ...
     }
 }
二货你真萌 2024-08-19 20:18:09

低技术含量的解决方案。使用具有所需范围的常规指针。

low tech solution. use a regular pointer with the scope you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文