Cで関数をパラメーターとして渡す方法のように、C++で関数をパラメーターとして渡す方法はありますか? 関数ポインターを使用して、C で関数をパラメーターとして渡すことができることを知っています。C++ でも同じことが可能かどうかを知りたいです。
5 に答える
C のように行うことができます。ただし、C++ の方法 (正確には C++11) で行うこともできます。
// This function takes a function as an argument, which has no
// arguments and returns void.
void foo(std::function<void()> func)
{
// Call the function.
func();
}
通常の関数を foo() に渡すことができます
void myFunc();
// ...
foo(myFunc);
ただし、ラムダ式を渡すこともできます。例えば:
foo([](){ /* code here */ });
関数オブジェクト (()
演算子をオーバーロードするオブジェクト) を渡すこともできます。一般に、演算子で呼び出すことができるものは何でも渡すことができます()
。
代わりに C の方法を使用する場合、渡すことができるのは通常の関数ポインターだけです。
C++ でも C と同じように関数をパラメーターとして渡すことができますが、いくつかの違いがあります。ポインターの代わりに関数参照、可変個引数のテンプレート引数に加えてテンプレート型を使用できます。例えば:
関数参照:
C では、オブジェクトを参照渡しする機能がありません。ただし、これは C++ では可能です。
void f( void (&)() ) {}
f( h );
参照とポインターの違いは微妙ですが、重要です。たとえばNULL
、参照を期待する関数に or 0 を渡すことはできません。引数は、その型ですぐに満たされる必要があります。通常、ほとんどの場合、ポインターよりも参照の方が優先されます。
テンプレート:
テンプレートを使用すると、変数の型属性を持つ関数をパラメーターとして一般的に渡すことができます。
template <class T, class U>
void f( T (&)( U ) ) {}
上記の署名は、任意の戻り値の型またはパラメーター リストを持つ関数を受け入れます (唯一の欠点は、関数が 1 つの引数を取らなければならないことです)。
この機能に加えて、varaidicテンプレートを利用して、可変長のパラメーター リストを持つ関数を許可することもできます。
template <class T, class ...U>
void f( T (&)( U... ) ) {}
int h(int, int) { .. }
bool g(std::string) { .. }
f( h );
f( g );
の実装でf
は、以下を使用している場合、完全転送も使用できますU&&
。
template <class T, class ...U>
void f( T (&fun)( U&&...) ) {
// ...
fun( std::forward<U>(u)... );
}
一般に にバインドされるラムダもありますstd::function<T(U)>
。
はい、関数ポインタはC++でもCとまったく同じように機能します。
はい、次のように:
#include <stdio.h>
typedef void (*my_func)(int);
void do_something (my_func f)
{
f (10);
}
void square (int j)
{
printf ("squared: %d\n", j * j);
}
void cube (int j)
{
printf ("cubed: %d\n", j * j * j);
}
int main (int argc, char *argv[])
{
do_something (square);
do_something (cube);
}
出力は次のとおりです。
squared: 100
cubed: 1000
typedef は、do_something() の構文をもう少し読みやすくするためのものです。
すでに C++ を使用しているため、仮想関数を使用して同じことを実現する方がはるかに簡単な方法であることを指摘したいと思います。
はい、可能です。
実用的なサンプルプログラムを見つけました(オンラインでテストおよび編集でき、概念をよく示しています):http: //ideone.com/6kSTrp#view_edit_box
//this was taken from http://www.cprogramming.com/tutorial/function-pointers.html
#include <stdio.h>
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int); //pointer to an int function
foo = &my_int_func;
/* call my_int_func (note that you do not need to write (*foo)(2) ) */
foo( 2 );
/* but if you want to, you may */
(*foo)( 2 );
return 0;
}