2016-09-16 4 views
2

私はテンプレートファンクタの特定のインスタンス化に汎用ディスパッチ関数を作成しようとしています。私はこのようになります私の仕事の一部では一般的なパターンを持っている:boost :: bindオブジェクトを呼び出すときにテンプレートパラメータを明示的に指定する方法はありますか?

// func is some template function 
char f; 
if (f == 'B') return func<int8_t>(); 
else if (f == 'I') return func<int16_t>(); 
else if (f == 'L') return func<int32_t>(); 
// and so on 
私はに基づいて特定のテンプレート引数を使用して、指定された機能を起動する再利用可能なライブラリにこの共通ロジックをラップしたいと思います

ランタイム値。関数ポインタを使用して一般的に行うことはできません(テンプレートへのポインタを持つことはできないため)。Funcを使用するには、次のコードを使用します。

template <typename Func> 
void format_dispatch(Func func, char f) 
{ 
    if (f == 'B') func.template operator()<int8_t>(); 
    else if (f == 'I') func.template operator()<int16_t>(); 
    else if (f == 'L') func.template operator()<int32_t>(); 
} 

は限りFuncは、単一のテンプレート型の引数を取るoperator()を持っているとして、私は仕事をする上でたいと思います、そして、それは、次の例と同じように、行います。

#include <iostream> 
#include <stdint.h> 
#include <typeinfo> 

template <typename Func> 
void format_dispatch(Func func, char f) 
{ 
    if (f == 'B') func.template operator()<int8_t>(); 
    else if (f == 'I') func.template operator()<int16_t>(); 
    else if (f == 'L') func.template operator()<int32_t>(); 
} 

struct foo 
{ 
    template <typename T> 
    void operator()() const 
    { 
     std::cout << typeid(T).name() << std::endl; 
    } 
}; 

int main() 
{ 
    format_dispatch(foo(), 'B'); 
    format_dispatch(foo(), 'I'); 
} 

これはしかし制限ビットです。それは根本的なように見えないので、

int x; 
format_dispatch(boost::bind<void>(foo(), x)); 

しかし、これは動作しません:私はファンクタのコールオペレータは、のようなものをいくつかの引数を取る場合に対処するためにバインド式を渡すことができるようにしたいと思いますbind_tタイプでは、コールの演算子に対するテンプレート引数の明示的な指定がサポートされています。私が探しているインターフェイスを達成する方法はありますか?このアプリケーションでは、私はC++ 11を利用できません。 C++ 03のみでなければなりません。

答えて

2

あなたはboost::bindのようなタイプのものを作ることができます。

template<typename F, typename T1> 
struct TypedBind1 { 
    F f; 
    T1 t1; 
    template<typename T> void operator()() { 
    f.template operator()<T>(t1); 
    } 
}; 

template<typename F, typename T1> 
TypedBind1<F, T1> MakeTypedBind1(F f, T1 t1) { 
    TypedBind1<F, T1> result = { f, t1 }; 
    return result; 
}; 

使用例:C++ 11の可変引数テンプレートなし

struct bar { 
    template <typename T> 
    void operator()(int x) const { 
    std::cout << x << " " << typeid(T).name() << std::endl; 
    } 
}; 

int main() 
{ 
    format_dispatch(foo(), 'B'); 
    format_dispatch(foo(), 'I'); 
    int x = 42; 
    format_dispatch(MakeTypedBind1(bar(), x), 'B'); 
    format_dispatch(MakeTypedBind1(bar(), x), 'I'); 
} 

、あなたは、引数の数ごとにこれを繰り返して(または多分Boost.PreprocessorまたはBoost.MPLの魔法を使用)する必要がありますあなたはBoostのようにサポートしたいと思っています。

+1

[完全な例](http://coliru.stacked-crooked.com/a/abf64278fc48f371)この回答の指示に従ってください。 – llonesmiz

関連する問題