「内部構造体」メンバーへのポインタは禁止されていますか? 質問する

「内部構造体」メンバーへのポインタは禁止されていますか? 質問する

ネストされた構造体があり、ネストされたメンバーの 1 つへのメンバーへのポインターが必要です。

それは合法ですか?

struct InnerStruct
{
    bool c;
};
struct MyStruct {
    bool t;
    bool b;
    InnerStruct inner;
}; 

これ:

MyStruct mystruct;
//...
bool MyStruct::* toto = &MyStruct::b;

大丈夫ですが:

bool MyStruct::* toto = &MyStruct::inner.c;

ありません。何か考えはありますか?

ありがとう

詳細は次のとおりです。はい、これは &MyStruct::b であり、mystruct::b; ではありません。コードはカスタム RTTI/プロパティ システムからのものです。指定されたクラスごとに、Ptr-to-member を含む「プロパティ」の配列を保持します。これは次のように使用されます。

//somewhere else in code...
( myBaseClassWithCustomRTTIPointer)->* toto = true;

ベストアンサー1

はい、それは禁止されています。この完全に論理的なアイデアを思いついたのは、あなたが初めてではありません。私の意見では、これは C++ のメンバへのポインタの仕様における明らかな「バグ」/「省略」の 1 つですが、どうやら委員会はメンバへのポインタの仕様をさらに開発することに関心がないようです (ほとんどの「低レベル」言語機能の場合と同様です)。

この機能を実装するために必要なものはすべて、言語内にすでに存在していることに注意してください。メンバーのデータ メンバーへのポインターは、直接のデータ メンバーへのポインターとまったく同じです。唯一欠けているのは、そのようなポインターを初期化する構文です。ただし、委員会は明らかにそのような構文を導入することに興味がありません。

純粋に形式論理の観点から言えば、これはC++で許可されるべきだった。

struct Inner {
  int i;
  int j[10];
};

struct Outer {
  int i;
  int j[10];
  Inner inner;
};

Outer o;
int Outer::*p;

p = &Outer::i; // OK
o.*p = 0; // sets `o.i` to 0

p = &Outer::inner.i; // ERROR, but should have been supported
o.*p = 0; // sets `o.inner.i` to 0

p = &Outer::j[0]; // ERROR, but should have been supported
o.*p = 0; // sets `o.j[0]` to 0
// This could have been used to implement something akin to "array type decay" 
// for member pointers

p = &Outer::j[3]; // ERROR, but should have been supported
o.*p = 0; // sets `o.j[3]` to 0

p = &Outer::inner.j[5]; // ERROR, but should have been supported
o.*p = 0; // sets `o.inner.j[5]` to 0

データ メンバーへのポインターの典型的な実装は、囲んでいるオブジェクトの先頭からのメンバーのバイト オフセットにすぎません。すべてのメンバー (即時メンバーとメンバーのメンバー) は最終的にメモリ内に順番に配置されるため、メンバーのメンバーも特定のオフセット値で識別できます。この機能の内部動作はすでに完全に実装されており、必要なのは初期化構文だけだと私が言うのは、このためです。

C 言語では、この機能は標準offsetofマクロを通じて取得される明示的なオフセットによってエミュレートされます。また、CI ではoffsetof(Outer, inner.i)およびを取得できますoffsetof(Outer, j[2])。残念ながら、この機能は C++ のデータ メンバーへのポインターには反映されません。

おすすめ記事