28

関数の型を理解するのに問題があります (たとえば、Signaturea のテンプレート パラメーターとして表示されますstd::function)。

typedef int Signature(int); // the signature in question

typedef std::function<int(int)>  std_fun_1;
typedef std::function<Signature> std_fun_2;

static_assert(std::is_same<std_fun_1, std_fun_2>::value,
              "They are the same, cool.");

int square(int x) { return x*x; }

Signature* pf = square;   // pf is a function pointer, easy
Signature f;              // but what the hell is this?
f(42);                    // this compiles but doesn't link

変数fを割り当てることはできませんが、呼び出すことはできます。変。では、何の役に立つのでしょうか?

ここで、typedef を const 修飾しても、それを使用してさらに型を構築できますが、明らかにそれ以外の目的はありません。

typedef int ConstSig(int) const;

typedef std::function<int(int) const>  std_fun_3;
typedef std::function<ConstSig>        std_fun_4;

static_assert(std::is_same<std_fun_3, std_fun_4>::value,
              "Also the same, ok.");

ConstSig* pfc = square; // "Pointer to function type cannot have const qualifier"
ConstSig fc;            // "Non-member function cannot have const qualifier"

ここで私は言語のどの隅にぶつかったのでしょうか? この奇妙な型はどのように呼び出され、テンプレート パラメーター以外で何に使用できますか?

4

2 に答える 2

28

これは、標準の関連する段落です。それはほとんどそれ自体を物語っています。

8.3.5/10

関数型の typedef は、関数を宣言するために使用できますが、関数を定義するために使用してはなりません (8.4)。

例:

typedef void F();
F  fv;         // OK: equivalent to void fv();
F  fv { }      // ill-formed
void fv() { }  // OK: definition of fv

宣言子にcv-qualifier-seqが含まれる関数型の typedef は、非静的メンバー関数の関数型を宣言するため、メンバーへのポインターが参照する関数型を宣言するため、またはトップを宣言するためにのみ使用されます。別の関数 typedef 宣言のレベル関数型。

例:

typedef int FIC(int) const;
FIC f;               // ill-formed: does not declare a member function
struct S {
  FIC f;             // OK
};
FIC S::*pm = &S::f;  // OK
于 2013-07-03T11:18:47.087 に答える
3

あなたの場合、std_fun_1std_fun_2は、同一の型シグネチャを持つ同一のオブジェクトです。どちらもstd::function<int(int)>であり、どちらも関数ポインタまたは型の呼び出し可能なオブジェクトを保持できますint(int)

pfへのポインタint(int)です。つまり、 と同じ基本的な目的を果たしますが、std::functionそのクラスの機構や呼び出し可能なオブジェクトのインスタンスのサポートはありません。

同様に、std_fun_3std_fun_4は同じ型シグネチャを持つ同一のオブジェクトであり、両方とも関数ポインターまたは型の呼び出し可能なオブジェクトを保持できますint(int) const

同様に、pfcは 型の関数ポインタでありint(int) const、その型の関数へのポインタを保持できますが、呼び出し可能なオブジェクトのインスタンスは保持できません。

ただしf、 andfc関数宣言です。

この線:

Signature fc;

以下と同等です:

int fc(int) const;

fctypeという名前の関数の宣言ですint(int) const

ここで奇妙なことは何も起こっていません。慣れていない観点から、おそらく既に理解している構文にたまたま遭遇しただけです。

于 2013-07-03T11:16:54.007 に答える