関数を受け取り、それを呼び出して返す関数を作成しようとしています。多くのテンプレートの組み合わせを含め、すでにいくつかのことを試しましたが、どれも機能していないようです。これを行う正しい方法は何ですか?
4 に答える
template <typename Functor>
Functor your_function(Functor toCall)
{
toCall();
return toCall;
}
ファンクターが返すものを返したい場合は、次のようなものを使用します。
// Requires C++11
#include <type_traits>
template <typename Functor>
typename std::result_of<Functor()>::type your_function(Functor toCall)
{
return toCall();
}
また、これは C++14 では次のように簡単になることに注意してくださいdecltype(auto)
。
//Requires C++14
template <typename Functor>
decltype(auto) your_function(Functor toCall)
{
return toCall();
}
ある関数が別の関数をパラメーターとして受け取ることはできません。C ではそれが許可されておらず、C++ でも許可されていません。
ただし、関数へのポインターをパラメーターとして渡し、そのポインターを介して関数を呼び出すことはできます。
#include <iostream>
int f() { std::cout << "called f\n"; return 2; }
typedef int (*ptr)();
int g(ptr p) { return p(); }
int main(){
std::cout << g(f);
}
結果:
called f
2
関数の代わりに関数テンプレートを使用する場合は、関数の名前をテンプレート パラメーターとして渡して呼び出すことができます。ただし、ほとんどの場合、operator()
関数の代わりにファンクター (関数のように呼び出すことができるようにオーバーロードするクラスのインスタンス) を使用することをお勧めします。
アルゴリズム:
- 関数が関数ポインタであるパラメータを受け取るようにします。
- 関数ポインタを使用して関数を呼び出します。
- 関数ポインタを返します。C および C++ では、関数はファースト クラス オブジェクトではありません。したがって、関数へのポインタを使用する必要があります。
パラメータの 1 つとして関数ポインタが渡される関数の構文を次に示します。
int Func (int (*funcToCall) (int, int)) /* This is how to receive the function as a parameter */
{
int val = funcToCall (1, 2); /* This is how to call the function once it's received as a parameter */
return (val);
}
int FuncToBePassed (int x, int y) /* This is a sample function that fits the format we need to pass into Func */
{
return (x+y);
}
printf ("%d\n", Func (FuncToBePassed)); /* This is how to pass the function reference to the first function */
したがって、この例では、2 つの int パラメーターを持つ関数 (FuncToBePassed) と、FuncToBePassed のような関数が渡されることを期待する関数 (Func) があります。最後に、コードの最後の行はそれを行い、Func を呼び出して FuncToBePassed への参照を渡します。
ところで、C++ の使用に完全にコミットしていない場合は、代わりに C# を使用することを強くお勧めします。関数を渡すなどの詳細は、はるかに優れた設計になっているからです。したがって、ある言語を習得するのに時間を費やすつもりなら、より実用的な言語を選びましょう。既に C++ で書かれているコードを維持している場合を除き、これは理解できます... 質問に答えていただければ幸いです。