mSDNによると、typedef構文は次のとおりです。
typedef type-declaration synonym;
非常に簡単:
typedef int MY_INT;
しかし、メンバー関数ポインターのtypedefはこの規則にどのように準拠しているのでしょうか。
typedef int (MyClass::*MyTypedef)( int);
100%混乱–同義語(MyTypedef
)が真ん中にある?
誰かが、MSDNの非常に理解しやすい構文形式から、上記のtypedefの逆/ランダム/フロント/ラスト/混合構文に至るまでの論理的な手順を説明できますか?
*すべての高速回答(および私の投稿の美化)に感謝を編集:)
同義語(MyTypedef)は真ん中にありますか?
真ん中にはありません。しばらくメンバー関数を忘れて、関数ポインターがどのように定義されているかを見てください:
int (*FuncPtr)(int);
そして、これはあなたがそれをtypedefする方法です:
typedef int (*FuncPtr)(int);
シンプル!唯一の違いは、typedefではFuncPtr
がtypeになるのに対し、ポインタ宣言ではFuncPtr
はvariableになります。
同様に、
int (MyClass::*MyTypedef)( int); //MyTypedef is a variable
そしてtypedefは次のようになります:
typedef int (MyClass::*MyTypedef)( int); //MyTypedef is a type!
C++ 11以降、この式を読みやすいusing
ステートメントとして記述できることに注意してください。
using MyTypedef = int (MyClass::*)(int);
メンバー関数へのポインターをどのように定義しますか?このような:
int (A::*variableName)(int);
Typedefにするには、typedefを追加するだけです。
typedef int (A::*typedefName)(int);
C++での宣言の原則は、それらが使用法を模倣することです。メンバー関数pmfへのポインターを使用する場合は、次のように記述します。
(myVar.*pmf)(arg);
typedefを定義するには、次のように記述します。
typedef int (MyClass::*pmf)(int);
先頭に戻りの型を追加し、変数を型に、引数を型に置き換えます。
私はあなたがすでにあなたの答えを得たことを知っていますが、これを共有したいのです-それは便利です http://www.cdecl.org 。 C/C++宣言<->英語翻訳者です。入力するだけ
クラスAのメンバーへのポインターとしてxを宣言します(int)charを返します
そしてchar (A::*x)(int )
を取得します。または、宣言をいじって、必要なものが得られるかどうかを確認します。
メンバー関数ポインターを使用する構文は、次のようにする必要があります(a
はクラスA
のインスタンスであると想定):
以下はおもちゃの例です。あなたはそれで遊ぶことができます。
#include <stdio.h>
#include <stdlib.h>
class A;
typedef int (A::*F)(double);
class A {
public:
int funcDouble(double x) { return (int)(x * 2.0); }
int funcTriple(double x) { return (int)(x * 3.0); }
void set(int a) {
if (a == 2) {
this->f_ = &A::funcDouble;
} else if (a == 3) {
this->f_ = &A::funcTriple;
} else {
this->f_ = NULL;
}
}
public:
F f_;
};
int main(int argc, char *argv[]) {
A a;
a.set(2);
F f = &A::funcDouble;
printf("double of 1 = %d\n", (a.*f)(1));
// Below is equivalent to:
// F f2 = a.f_;
// printf("double of 1 = %d\n", (a.*f2)(1));
printf("double of 1 = %d\n", (a.*(a.f_))(1));
a.set(3);
printf("triple of 1 = %d\n", (a.*(a.f_))(1));
return 0;
}
あなたが参照しているページは、おそらく " typedef Specifier "です。単純化された "typedef type-declaration synonim;
"構文はtypedefを使用する多くの方法の1つにすぎません。typedefの使用方法を説明する単純で簡潔な方法は(おそらく)ありません。それが" Typedef Declarations "MSDNページです。のためです。
このページでは次のように気づくでしょう:
declaration:
declaration-specifiers init-declarator-list opt ;
declaration-specifiers:
storage-class-specifier declaration-specifiers opt
type-specifier declaration-specifiers opt
type-qualifier declaration-specifiers opt
storage-class-specifier:
typedef
どの宣言宣言子とinit-declarator-listが見つかるかについての詳細 here 。
これは、「typedef」のすべての可能な使用法を理解するための1つの厳密な方法です。
このページで基本的に言っているのは、「typedef」はほとんどの有効な宣言の前に使用できるということです。
私は一度素敵な説明を読んだことがあります(しかし、それは Expect C Programming からのものなので、私はymmvです):
実際、typedefの形式は変数の宣言とまったく同じですが、このキーワードを追加するだけでヒントになります。
Typedefは変数宣言とまったく同じように見えるので、変数宣言とまったく同じように読み取られます。 「この名前は指定されたタイプの変数を参照しています」と宣言する代わりに、typedefキーワードは変数を作成しませんが、「この名前はの同義語です。指定されたタイプ。」
だからあなたはそれを持っています。変数を宣言していると想像してみてください。変数の前にtypedef
を付けておくと、新しい型になります。 MSDN
説明は混合されたバッグです:私は本当に神のものと全く悪いものを読みました。
次のように考え始めると、理解しやすくなります。
次のような関数が見つかるときはいつでも:
TYPE foo(int arg1, int arg2);
FooのタイプはTYPEであると言います。したがって、タイプ
int get_next_prime();
intです。
関数ポインタを関数の引数として渡すと、次のことがわかります。
void register_callback(void (*ptr)(int));
この場合、タイプvoidの関数を引数として渡します。
今、あなたはそのようなものを見たとき:
typedef int (A::*typedefName)(int);
変数(A :: * typedefName)(int)(これは関数ポインタ宣言であるため、2つではなく1つだけです)は実際にはint型であると言っているだけです。それ以降、コンパイラはA :: * typedefNameをint型の関数として解釈します。つまり、int値を返します。
混乱が少なくなることを願っています。