2016-11-18 5 views
1

私は以下のようなバリデーショナルテンプレートメンバー関数(foo)を持つクラスを持っています。この考え方は、パラメータ内のすべての倍精度浮動小数点数をスキップして、ユーザーが指定した引数でオブジェクトを割り当てることです。バリデーショナルテンプレート関数のオーバーロード

template <class T> 
    class Var { 
    public: 

     template <typename U, typename ...Args> 
     int foo(int index, Args... args) 
     { 
      T* p = new U(args...); 
      // save in an array at index 'index' 
     } 

     template <typename U, typename ...Args> 
     int foo (double index, Args... args) 
     { 
      // do something with index and skip it 
      return foo<U>(args...); 
     } 
    }; 

    class A { 
    public: 
     A (int i, const char *p) 
     { 

     } 
    }; 

    int main() 
    { 
     Var<A> var; 

     var.foo<A>(1.0, 2, 3, "Okay"); 
    } 

これで問題は2つあります。

  • スキップする倍数を指定します.Eg:2倍をスキップし、次の引数はintにする必要があります。そうでない場合は、エラーをスローします。

  • 「double」の代わりに「int」を使用します。したがって、2つのintをスキップします。次のインデックスは配列のインデックスになります。

基本的には、クラステンプレートパラメータとしてスキップするintの数。

スキップするスキップする整数の数を決定するには、SKIPを使用します。

このようなことは可能ですか?あなたのSKIP目標の

+0

私はそういうことをすることは可能だと思いますが、結果として得られるコードはむしろ醜いかもしれません。これはちょうど学問的質問か、あなたが解決しようとしている実用的な問題がありますか?正確な質問を述べると、正しい行動が得ようとしているかのように役立ちます。 –

+0

これはより学問的です。私はNovelocratが提案したスキームに基づいて以下に追加した解決策を持っています。コードベースには、タイプORタイプとサブタイプに基づいてオブジェクトを格納する必要があった実際のユースケースがありました。したがって、検索関数は(int型)または(int型、int型)です。しかし、私はそこでこの計画を使用しませんでした。 2つの特殊なクラスを使用するより簡単な解決方法を考えてみましたが、同じ関数(関数名)を異なる引数セットで再定義しました。 – MGH

答えて

1

これは私がNovelocratからヒントを取って思いついたものです。それを貼り付けるだけでレコードが聞こえます。

template <class T, int SKIP> 
class FooHelper { 
public: 

    template <typename U, typename ...Args> 
    static int foo_helper(int index, Args... args) 
    { 
     FooHelper<T, SKIP-1>::foo_helper<U>(args...); 
     return 0; 
    } 
}; 

template <class T> 
class FooHelper<T, 0> { 
public: 

    template <typename U, typename ...Args> 
    static int foo_helper (Args... args) 
    { 
     auto p = new U(args...); 
     return 0; 
    } 
}; 

template <class T, int SKIP> 
class Var { 
public: 

    template <typename U, typename ...Args> 
    int foo(Args ...args) 
    { 
     FooHelper<T, SKIP>::foo_helper<U>(args...); 
     return 0; 
    } 
}; 
1

は、あなたがこのような何かを行うことができます:

template <typename U, typename ...Args> 
int foo(Args ...args) { 
    return foo_helper<U, 0>(std::forward(args)); 
} 

template <typename U, int I, typename ...Args> 
int foo_helper(int index, Args ...args) { 
    return foo_helper<U, I+1>(std::forward(args)); 
} 

template <typename U, typename ...Args> 
int foo_helper<U, SKIP, Args...>(int index, Args ...args) { 
    blah = new U(std::forward(args)); 
    return foobar; 
} 

は基本的には、ターゲットにカウントアップし、それが到達されるまでの引数を取り除く方法があります。目標値を特殊化する。また

、ないあなたはおそらく引数が参照を維持するforward、したいと思うことなど

私はC++ 14本の簡単にいくつかを作るかもしれないと考えているが、私は、新しいテンプレートと十分に熟知していませんよそれに対処するメタプログラミング技術。

+0

答えをありがとう。しかし、ここでは機能テンプレートの部分的な特殊化はしていませんか?それはコンパイルされません。しかし、テンプレートクラスの特殊化と同じテクニックが働きます。 – MGH

+0

あなたはそうです、それは関数テンプレートの部分的な特殊化です。私は上記のコードを使って直接考えたり、テストしたりしませんでした。しかし、はい、それは常にクラステンプレートにラップアップされて動作させることができます。 – Novelocrat

関連する問題