2017-09-03 13 views
2

私が取り組んでいるゲームの(G)UIシステム用のあらゆる種類の関数に任意の種類のイベントをバインドしたいと思います。関数の引数を格納できるFunctorテンプレートの実装

私はシグナルバインディングインデックスにバインドすることができるFunctorテンプレートクラスに任意の種類の関数とその初期引数を格納したいと思います。シグナルバインディングにバインドされたイベントは、イベントキューに表示されるとトリガーされ、このバインディングにバインドされたすべてのFunctorsが呼び出されます。

関数の引数を格納する方法は、ファンクタテンプレートでstd::tupleを使用することでしたが、関数を呼び出すときに正しく初期化して適切にアンパックする必要があります。

この

は、私がこれまで持っているものです。

  • 私がするために正しくパラメータパックArgsを使用するにはどうすればよい

    template<typename R, typename... Args> 
    class FuncBinding { 
    private: 
        std::tuple<Args...> args; 
        R(*fun)(Args...); 
    
    public:    
        FuncBinding(R(*pF)(Args...) , Args... pArgs) 
         :fun(pF), args(std::make_tuple<Args...>(pArgs)) {} 
    
        R invoke() { 
         return fun(args...); 
        } 
    
        R callFunc(Args... pArgs) { 
         return fun(pArgs...); 
        } 
    }; 
    

    を... ...テンプレートクラスを作成std::tuple<Args...> appropiately

  • ... std::tuple<Args...>インスタンスargsをファンクション引数で初期化
  • ...アンパックth

    FuncBinding(R(*pF)(Args...) , Args... pArgs) 
    : fun(pF), args(pArgs...) 
    { } 
    

    :あなたはちょうどそのコンストラクタにパックを渡して、それを初期化するように、関数ポインタを通じて関数を呼び出すEタプルはR(*fun)(Args...)

+0

可能(https://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer/20441189#20441189)。 – Walter

答えて

3

tuple、初期化の観点からだけで別のクラス型でありますまたは、より効率的に:

args(std::forward<Args>(pArgs)...) 

私はforward代わりの場合はstd::move()Args...の一部を使用しています左辺値の参照型です。呼び出し側では


、C++ 17機能が何をしたいんどのstd::apply()が呼び出されます。

R invoke() { 
    return std::apply(fun, args); 
} 

それはC++ 11で実施可能です。 cppreferenceページには、std::make_index_sequenceを含む実装が含まれています。この実装自体はC++ 11で実装可能です(このサイトにはこのような実装が多数あります)。

+0

ありがとうございます。私は、C++ 17のソリューション( 'std :: apply')を使うのが一般的に好まれると思いますか? – stimulate

+0

@stimulate C++ 17コンパイラを使用している場合は、 'std :: apply()'を直接使用します。これはすでに書かれています。そうでない場合は、自分で実装する必要がありますが、そうするのは難しくありません。 – Barry

+1

興味のある人には、C++ 11の 'index_sequence'の実装があります:https://stackoverflow.com/a/24481400/1944004 –

関連する問題