2017-02-16 2 views
1

与えられたパラメータで関数を呼び出すことができるテンプレート関数を記述したいと思います。引数よりもパラメータの多い関数/ファンクタを呼び出す

template<class F, class... Args> 
inline auto invoke(F &&func, Args&&... args) -> decltype(auto) 
{ 
    return std::forward<F>(func)(std::forward<Args>(args)...); 
} 

このinvokefが必要とするパラメータの同じカウントを受け付けます。

例えば、私は、単純な関数invokeを書くことができます。しかし、私はこのテンプレート関数に追加の未使用のパラメータを許可したい。ある は、私のようないくつかのコードを書きたい:

ここ
auto f = [] (auto a) {...}; 
invoke(f, 1, 2, 3); 

は、fは、唯一のパラメータは、そう、私はinvokeは最初のものを除いて、他のパラメータを無視したい受け入れます。 これは、ラムダが一般的でない限りラムダを得ることによって非常に容易に達成することができる。 f以来

ここでは、私の知る限り、そのtemplate operator()<...>の明示的なインスタンスなしfのアリティを把握するという一般的な方法はありません、一般的なラムダです。

どうすればいいですか?invoke

答えて

4

一つの可能​​性:

#include <utility> 
#include <cstddef> 
#include <tuple> 

template <std::size_t... Is, typename F, typename Tuple> 
auto invoke_impl(int, std::index_sequence<Is...>, F&& func, Tuple&& args) 
    -> decltype(std::forward<F>(func)(std::get<Is>(std::forward<Tuple>(args))...)) 
{ 
    return std::forward<F>(func)(std::get<Is>(std::forward<Tuple>(args))...); 
} 

template <std::size_t... Is, typename F, typename Tuple> 
decltype(auto) invoke_impl(char, std::index_sequence<Is...>, F&& func, Tuple&& args) 
{ 
    return invoke_impl(0 
        , std::index_sequence<Is..., sizeof...(Is)>{} 
        , std::forward<F>(func) 
        , std::forward<Tuple>(args)); 
} 

template <typename F, typename... Args> 
decltype(auto) invoke(F&& func, Args&&... args) 
{ 
    return invoke_impl(0 
        , std::index_sequence<>{} 
        , std::forward<F>(func) 
        , std::forward_as_tuple(std::forward<Args>(args)...)); 
} 

DEMO

+0

無関係:呼び出し可能なオブジェクトの場合、これは時々パラメータの最小数を有する '演算子()'呼び出します。それは最高の試合を呼び出すことは可能ですか? – felix

+0

@felix私は気づいていません。多分ラムダオブジェクトから継承して演算子()をインポートするかもしれませんが、少なくとも1人はすべてのパラメータを受け入れるべきです。私は他の可能性を排除することはできません。 –

+0

ああ、賢いテンプレートのメタプログラミングコードを見るのはいつも印象的です!ありがとうございました。 – xylosper

関連する問題