2017-02-25 7 views
0

パラメータの数が0以外の関数を受け取り、1つのパラメータしか取らない関数にstd :: bindを使用して関数を受け入れるプログラムを作成しようとしています。関数がすべての種類の関数を受け入れるためにオーバーロードする

問題の後半部分は問題ありませんが、std :: function、function pointer、functorまたはlambdaのような任意のタイプの関数を入力できるようにしたいと思います。テンプレートの記述方法はわかりません最後の2つの型を受け入れ、関数が取る引数の数を推測できるようにするパラメータ。

関数ポインタとstd ::関数を受け入れるためにオーバーロードされる 'foo'関数を使用したサンプルコードを見てください。他の2つのオーバーロードを書く方法について誰かが正しい方向に向けることができたら、感謝します。このような

#include <functional> 
#include <iostream> 

template <typename Ret, typename ParamA, typename... Params> 
unsigned int foo(const std::function<Ret(ParamA, Params...)>& f) 
{ 
    return sizeof...(Params); 
} 

template <typename Ret, typename ParamA, typename... Params> 
unsigned int foo(Ret(*f)(ParamA, Params...)) 
{ 
    return sizeof...(Params); 
} 

unsigned int foo(/*accepts a functor*/); 

unsigned int foo(/*accepts a lambda*/); 

std::function<void(int)> std_func([](int) {}); 
void f_ptr(int, int) {} 
struct functor { void operator() (int, int, int) {} }; 
auto lambda = [](int, int, int, int) {}; 

int main() 
{ 
    std::cout << foo(std_func); //Passed in a std::function 
    std::cout << foo(f_ptr); //Passed in a function pointer 
    std::cout << foo(functor()); //Passed in a functor 
    std::cout << foo(lambda); //Passed in a lambda 

    return 0; 
} 
+0

問題は明確に定義されていません。ファンクタ( 'operator()'を持つクラス)は、異なる数と型のパラメータを取って、 'operator()'の複数のオーバーロードを提供するかもしれません。あなたの機能はどれですか? –

+0

'std :: bind'は呼び出し可能なオブジェクトのパラメータをバインドするので、心配する必要はありません。しかし、あなたが完全に説明していないことの1つは、正確に各パラメーターをバインドしたいものです。指定されていないものにパラメータをバインドすることはできません。 'std :: bind'の目的は、関数のパラメータに離散値を代入することです。では、あなたは正確に何をバインドしようとしていますか? –

+0

@SamVarshavchikたとえば、整数パラメータを取り、そのパラメータの位置をバインドする関数を受け入れることができます。たとえば、foo(int a、int b、int c)はfoo(int a、1,2)になります。 ) –

答えて

0

何か:

// Accepts a pointer to member function 
template <typename T, typename Ret, typename ParamA, typename... Params> 
unsigned int foo(Ret (T::*f)(ParamA, Params...)) 
{ 
    return sizeof...(Params); 
} 

// Accepts a pointer to const member function 
template <typename T, typename Ret, typename ParamA, typename... Params> 
unsigned int foo(Ret (T::*f)(ParamA, Params...) const) 
{ 
    return sizeof...(Params); 
} 

// Accepts a function object, including lambda and std::function 
template <typename F> 
unsigned int foo(const F& func) { 
    return foo(&F::operator()); 
}  

は一つだけ、非オーバーロードさoperator()と関数オブジェクト上で動作します。 std::functionもこのようなオブジェクトであるため、std::functionの専用オーバーロードは不要です(しかし、プレーン関数ポインタ用のものも必要です)。

Demo

関連する問題