2016-03-31 32 views
1

C++では、引数を引数として関数を渡すことは可能ですか?私は関数名を渡すだけではありません。私は、パラメータを含む関数名を渡したいと思います。関数が受け取るパラメータの数や型はどれくらいかわかりません。だから、私は余分なパラメータとしてそれらを追加していません。私は、必要に応じて実行できる関数呼び出しを参照したいだけです。たとえば:C++の引数を持つ関数を渡す

CallFunction(f(param1, param2)); 

しかし、fが評価されていない、私は関数呼び出しへの参照を取得し、私が欲しいとき、私は例えば、それを評価することができます。

​​

これは缶の中の任意の方法C++で達成されるでしょうか?前もって感謝します。

+4

[std :: bind](http://en.cppreference.com/w/cpp/utility/functional/bind)。 – songyuanyao

+0

@songyuanyaoは、その文字列の情報を文字列として得ることができます。呼び出されている関数のbañe? –

+0

申し訳ありませんが、 'bañe'とは何ですか? – songyuanyao

答えて

0
  1. 最初の引数
  2. 可変引数テンプレートを使用して、任意のタイプの任意の数の引数を受け入れるよう任意の呼び出し可能な関数を受け入れます。
  3. 完璧な転送を使用します。

http://ideone.com/z2kLUx

int HelloWorld(string var1, const char* var2) 
{ 
    cout << var1 << " " << var2 << endl; 
    return 5; 
} 

template<typename Fn, typename... Args> 
auto CallFunction(Fn fn, Args&&... args) 
{ 
    return fn(forward<Args>(args)...); 
} 

int main() 
{ 
    cout << "Value returned: " << CallFunction(HelloWorld,"Hello","World"); 
    return 0; 
} 

これは欠点があり、単純なバージョンです:あなたは非voidを返す関数を指定する必要がありますが、これは簡単に修正することができます。簡単な修正は、異なる名前のvoidを返す別のCallFunctionを作成するか、std::enable_ifを使用します。

http://ideone.com/El3WUi

template<typename Fn, typename... Args> 
auto CallFunction(Fn fn, Args&&... args) -> typename enable_if<is_same<void, decay_t<decltype(fn(forward<Args>(args)...))>>::value, decltype(fn(forward<Args>(args)...))>::type 
{ 
    fn(forward<Args>(args)...); 
} 

template<typename Fn, typename... Args> 
auto CallFunction(Fn fn, Args&&... args) -> typename enable_if<!is_same<void, decay_t<decltype(fn(forward<Args>(args)...))>>::value, decltype(fn(forward<Args>(args)...))>::type 
{ 
    return fn(forward<Args>(args)...); 
} 
3

std::bindを使用しての完全な例:

#include <iostream> 
#include <functional> 

void f(int p1, int p2) { 
    std::cout << "In f(" << p1 << "," << p2 << ")\n"; 
} 

template <typename F> 
void CallFunction(F f) 
{ 
    std::cout << "Start CallFunction\n"; 
    f(); 
    std::cout << "End CallFunction\n"; 
} 

int main() 
{ 
    CallFunction(std::bind(f, 2, 3)); 
} 
0

あなたはいくつかのオプションがあります。

1つは、関数の呼び出しをカプセル化するラッパークロージャを作成することです。これは、必要に応じて関数の出力を変換できるという利点があります。

シンプルなラッパーを使用することは、前述したようにstd::bindを使用することと同じです。

#include <functional> 
#include <iostream> 

void CallFunction(std::function<void(void)> f) { 
    f(); 
} 

int main() { 
    auto closure = [](int a, int b) { 
     std::cout << a << ", " << b << std::endl; 
    }; 

    auto wrapper = [closure]() { 
     closure(1, 2); 
    }; 

    CallFunction(wrapper); 

    CallFunction(std::bind(closure, 3, 4)); 

    return 0; 
} 
関連する問題