2017-12-27 10 views
0

正しい関数テンプレートを推論するためにコンパイラを取得しようとしています。 は、次のコードを考えると、正しいテンプレート関数が推定される...オーバーロードされた関数ポインタをオーバーロードされたテンプレート関数の引数として渡します。

class TestBase{}; 

template <typename c, typename RT, typename T0> 
inline void CallF(RT(c::*M)(T0), TestBase* pObject, std::vector<OVariant> args) 
{ 
    //safely convert variant (implementations external to class) 
    T0 t0 = args[0].GetSafe<T0>(); 

    ((static_cast<c*>(pObject))->*M)(t0); 
} 

template <typename c, typename RT, typename T0, typename T1> 
inline void CallF(RT(c::*M)(T0, T1), TestBase* pObject, std::vector<OVariant> args) 
{ 
    //safely convert variant (implementations external to class) 
    T0 t0 = args[0].GetSafe<T0>(); 
    T1 t1 = args[1].GetSafe<T1>(); 

    ((static_cast<c*>(pObject))->*M)(t0, t1); 
} 

class Test : public TestBase 
{ 
public: 

    void F(s32 one) 
    { 
     std::cout << "one"; 
    } 

    struct Wrapped_F 
    { 
     //OVariant is my typical variant class 
     static void Call(TestBase* pObject, std::vector<OVariant> args) 
     { 
      ::CallF<Test>(&Test::F, pObject, args); 
     } 
    }; 
}; 

int main(int argc, char *argv[]) 
{ 
    Test t; 
    OVariant i(13); 
    std::vector<OVariant> args; 
    args.push_back(i); 

    t.Wrapped_F::Call(&t, args); 
} 

t.Wrapped_F ::コール(&トン、argsが)正しいF関数を呼び出します。私がテストするためにオーバーロードされたF関数、それ(2つの引数で過負荷)を追加した場合しかし、私はこれがのためであるかなり確信して

void F(s32 one, s32 two) 
{ 
    std::cout << "two"; 
} 

(1つの引数に代わり、正しいFの)と呼ばれますコンパイラが推測するのに十分な情報がないという事実。どのオーバーロードされたテンプレート関数を呼び出してコンパイラがどのように呼び出すのを助けることができますか?

(未知のタイプのいくつかの引数を示すため?)以下の擬似コードのようなもの...

static void Call(TestBase* pObject, std::vector<OVariant> args) 
{ 
    //Note: I won't know anything about the arguments to function F; I do know the size of the vector 
    switch (args.size()) 
    { 
    case 1:::CallF<Test,void,?>(&Test::F, pObject, args); 
    case 2:::CallF<Test,void,?,?>(&Test::F, pObject, args); 
    } 
} 

これを行うにはそこに方法は何ですか?

答えて

1

コンパイラは、バリアントクラス内に格納されているものを知る方法がありません。従って、?は、(そのパラメータからの)機能タイプからと推測することができます。したがって、args.size()が関数パラメータの数と一致することを確認するコードが必要になります。次の操作を実行してみてください。

  • Args...args.size()は、あなたのargsベクトルがタプルに変換std::tuple<Args...>
  • の要素数と同じであることを関数型
  • チェックから評価されている場合std::tuple<Args...>を作成します。
  • 使用std::apply(または再発明する独自の)タプルから引数
+0

であなたの関数を呼び出すように私はあなたのアイデアのバリエーションを試してみましたが、かなり右にフィットしていないようです。関数の型がコール関数でわかっていない場合、std :: tupleの作成方法はでしょうか? OVariant :: GetSafe(T0 t0 = args [0] .GetSafe ();)を呼び出す機能が失われますか? –

関連する問題