2017-05-11 7 views
2

以下のコードを単純化するにはどうすればよいですか?ここでタプルを使用するのは可能でしょうか?はいの場合は、どのように説明することができます。テンプレートの実装でパラメータとしてstd :: functionを使用するバリアリックテンプレート

template<typename Out, typename T1, typename T2, typename T3, typename T4> 
void ProcessIncomingCommand(PClientContext pClientContext, 
    DWORD & bytesProcessed, 
    const std::function<Out(T1, T2, T3, T4)> &function, 
    const std::vector<UINT> &params); 

template<typename Out, typename T1, typename T2, typename T3> 
static void ProcessIncomingCommand(PClientContext pClientContext, 
    DWORD & bytesProcessed, 
    const std::function<Out(T1, T2, T3)> &function, 
    const std::vector<UINT> &params); 

template<typename Out, typename T1, typename T2> 
static void ProcessIncomingCommand(PClientContext pClientContext, 
    DWORD & bytesProcessed, 
    const std::function<Out(T1, T2)> &function, 
    const std::vector<UINT> &params); 

UINTstd::vectorによって渡されたパラメータを使用して機能を呼び出すために必要とされます。パラメータは異なる可能性があるため、適切な型にキャストする必要があります。

auto resFromFunction= function(params.at(0), 
    params.at(1), 
    static_cast<T3>(params.at(2)), 
    static_cast<T4>(params.at(3))); 

ここではlog0答えを使用できますか?

template<typename Out, typename... T>static void ProcessIncomingCommand(PClientContext pClientContext, 
DWORD & bytesProcessed, 
const std::function<Out(T...)> &function, 
const std::vector<UINT> &params) 
+4

のような何かをしたいように見えますか?このコードの目的は何ですか? – InternetAussie

+0

タプルはどのように使用されますか? – log0

+0

実現では、私はUINTのベクトルによって渡されたパラメータで関数を呼び出します。ベクトルの型はテンプレートargs(T ...)と異なる場合があります。私はそれらを適切なタイプにキャストする必要があります。例:function(static_cast (params.at(0))、...)などここでテンプレートを使用するのは適切な方法ですか? –

答えて

2

わかりません...しかし、あなたは関数ヘルパーとstd::index_sequence(または類似のもの)が必要だと思います。 std::index_sequencestd::make_index_sequence()はC++ 14個の機能であること

可能な例

template <typename Out, typename ... Ts, std::size_t ... Is> 
static Out PIC_helper (
    PClientContext pClientContext, 
    DWORD & bytesProcessed, 
    const std::function<Out(Ts...)> &function, 
    const std::vector<UINT> &params, 
    std::index_sequence<Is...> const &) 
{ return function(static_cast<Ts>(params.at(Is))...); } 

template <typename Out, typename ... Ts> 
static void ProcessIncomingCommand (
    PClientContext pClientContext, 
    DWORD & bytesProcessed, 
    const std::function<Out(Ts...)> &function, 
    const std::vector<UINT> &params) 
{ 
    Out resFromFunction 
     = PIC_helper(pClientContext, bytesProcessed, function, params, 
        std::make_index_sequence<sizeof...(Ts)>()); 

    // other ... 
} 

Observere。 C++ 11ソリューションが必要な場合は、簡単に代用することができます。

+0

私はあなたのソリューションを実装してテストしようとしています。あなたの答えをありがとう。 –

+0

返品の種類を修正してもらえますか? –

+0

@SmitYcyken - 申し訳ありませんが、分かりません。 – max66

0

これはコンパイルされます。あなたはタプルとしてのparamsを渡したい場合は、トリッキーになるだろう

template<typename Out, typename... T> 
static void ProcessIncomingCommand(PClientContext pClientContext, 
    DWORD & bytesProcessed, 
    const std::function<Out(T...)> &function, 
    const T&... params) { function(params...); } 

int main() 
{ 
    PClientContext p; 
    DWORD d = 0.5; 
    std::function<int(double, int, char)> f; 
    double a; 
    int b; 
    char c; 
    ProcessIncomingCommand(p, d, f, a, b, c); 
} 

: あなたの代わりにパラメータのリストのタプルを取るためにfunctionを変更した場合はもちろん除きHow do I expand a tuple into variadic template function's arguments? を見る

+0

Nパラメータで関数を呼び出すにはどうすればよいですか?テンプレートの実装についての情報は、上記のコメントを見てください。 –

+1

ok私は、パラメータが 'function'に渡されることは明らかではありませんでした。答えを編集しました。 – log0

+0

誤解を招くものを許してください。 –

0

あなたは*本当に*ここでやろうとしている何

template<typename ResultType, std::size_t... I> 
ResultType tuple_from_vector_impl(std::vector<UINT> params, std::index_sequence<I...>) 
{ 
    return std::make_tuple(static_cast<decltype(std::get<I>(std::declval<ResultType>()))>(params[I])...); 
} 

template<typename... Args, typename Indices = std::index_sequence_for<Args...>> 
std::tuple<Args...> tuple_from_vector(std::vector<UINT> params) 
{ 
    return tuple_from_vector_impl<std::tuple<Args...>>(params, Indices{}); 
} 

template<typename Out, typename ... Args> 
void ProcessIncomingCommand(PClientContext pClientContext, 
          DWORD & bytesProcessed, 
          const std::function<Out(Args...)> &function, 
          const std::vector<UINT> &params) 
{ 
    // preamble 
    std::tuple<Args...> args = tuple_from_vector<Args...>(params); 
    Out result = std::apply(function, args); 
    // postamble 
} 

template<typename ... Args> 
void ProcessIncomingCommand(PClientContext pClientContext, 
          DWORD & bytesProcessed, 
          const std::function<void(Args...)> &function, 
          const std::vector<UINT> &params) 
{ 
    // preamble 
    std::tuple<Args...> args = tuple_from_vector<Args...>(params); 
    std::apply(function, args); 
    // postamble 
} 
関連する問題