16

関数ポインターのこのような構文を見るのに慣れています

int (*pointer_name) (float, char *);
void call_function (void (*)(int), int);

一部の C++03 機能ライブラリでは、型が次のように使用されているのを目にします。

abc::function<void(*)(int,float)> f;

C++11 ではstd::function、このように指定された型が表示されます

std::function<void(int,float)> f;

欠けがあり(*)ます。なんで?

C++03function<T>T、対応する関数ポインタと同じ型になっています。実装を想像するのは簡単です。

std::functionin C++11 は、コア言語の拡張機能によってサポートされています。呼び出し可能性に対応するために、テンプレート引数の型が拡張されていますか?

4

4 に答える 4

17

std::function(およびそのインスピレーション、boost::function)は関数ポインタを格納するだけではありません。関数オブジェクトを格納することもできます。その意味で、関数の署名をテンプレートパラメーターとして渡すことは、スマートポインターが通常、ポインターの型ではなく、ポインターの型をテンプレートパラメーターとして受け取る方法に似ています。

対比:

int* p; // indirection to an object of type int
std::unique_ptr<int> q; // indirection to an object of type int

typedef void signature_type(); // a function type

// indirection to something callable with signature_type as a signature
// i.e. f() has type void
// only work for freestanding functions however
signature_type* f;

// indirection to something callable with signature_type as a signature
// i.e. g() has type void
// not restricted to function pointers!
std::function<signature_type> g;

これは便利な規則です。

于 2011-08-30T15:18:59.493 に答える
8

他の要素と同様に、関数には型があり、さまざまなコンテキストで型または型へのポインターのいずれかを使用できます。(*)あなたが期待している欠落は、構文へのポインタにすぎません。

int (*pointer_name) (float, char *);
typedef int my_function_type(float,char*);
my_function_type * pointer_name2;

pointer_nameとの型はpointer_name2同じです。型の2つの引数を返し、受け取る関数へのポインタintfloatchar*。これはint、のような他の型とまったく同じですが、変数を関数型として宣言することはできず、関数へのポインタのみであるという違いがあることに注意してください。

std::function(またはboost::function)のインターフェースは、関数のシグネチャを取得するだけです。type引数は関数へのポインターではなく、関数の型です(my_function_type上記のコードのように)

于 2011-08-30T15:19:14.533 に答える
8

ここには何も魔法はありません、タイプ

void(int,float)

名前のない関数の型です。のような関数にマッチしますvoid g(int x, float y)

テンプレートでは、関数ポインターを使用する必要はなく関数型も使用できます。

于 2011-08-30T15:13:20.050 に答える
3

関数型は C++11 では新しくありません (C++98 の 8.3.5 を参照)。IIRC、TR1 とブーストが提供するものに対する改善functionはごくわずかです。

于 2011-08-30T15:12:31.033 に答える