4

テンプレートクラスがあります


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{}。また、事前にインスタンス化される型がわからないため、関数の最初で宣言することはできません。

コンパイル時に(テンプレートを使用して)実行時のことを達成しようとしていることは知っていますが、それでもこれを行うためのより良い方法があるかどうかを知りたいと思っていました。

4

5 に答える 5

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..
}
于 2009-11-27T08:33:20.853 に答える
4

に共通ベースを導入し、myClassそれをのパラメータとして使用できますauto_ptr。そのコモンベースのデストラクタを仮想として宣言することを忘れないでください。

于 2009-11-27T08:14:42.590 に答える
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テクニックは間違いなく進むべき道です。使用方法については、チュートリアルを参照してください。

于 2009-11-27T08:28:47.893 に答える
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>();
        // ...
     }
 }
于 2009-11-27T13:11:01.820 に答える
0

ローテクソリューション。必要なスコープで通常のポインターを使用します。

于 2009-11-27T12:52:54.917 に答える