関数タイプの理解に問題があります(たとえば、std::function
のSignature
テンプレートパラメータとして表示されます):
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"
私はここで言語のどの辺境をたどったのですか?この奇妙な型はどのように呼び出され、テンプレートパラメータの外で何を使用できますか?
これは規格の関連する段落です。それはほとんどそれ自体のために語っています。
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
あなたの場合、_std_fun_1
_と_std_fun_2
_は、同じ型シグネチャを持つ同じオブジェクトです。これらはどちらもstd::function<int(int)>
であり、どちらもint(int)
型の関数ポインタまたは呼び出し可能オブジェクトを保持できます。
pf
はint(int)
へのポインターです。つまり、_std::function
_と同じ基本的な目的を果たしますが、そのクラスの機構や呼び出し可能なオブジェクトのインスタンスのサポートはありません。
同様に、_std_fun_3
_と_std_fun_4
_は、同じ型シグネチャを持つ同一のオブジェクトであり、どちらも関数ポインタまたはint(int) const
型の呼び出し可能オブジェクトを保持できます。
同様に、pfc
はint(int) const
型の関数ポインターであり、その型の関数へのポインターを保持できますが、呼び出し可能なオブジェクトのインスタンスは保持できません。
ただし、f
とfc
は関数宣言です
この線:
_Signature fc;
_
次と同等です:
_int fc(int) const;
_
これは、タイプint(int) const
のfc
という名前の関数の宣言です。
ここで奇妙なことは何もありません。慣れていない視点から、おそらくすでに理解している構文に遭遇しただけです。