Является Pointer-to-“ внутренней структурой” запрещенный участник?

у меня есть вложенная структура, и я хотел бы иметь указатель на участника на одного из вложенного участника:

действительно ли это законно?

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 участнику, Это используется как это:

//somewhere else in code...
( myBaseClassWithCustomRTTIPointer)->* toto = true;
18
задан benoitj 18 December 2009 в 18:46
поделиться

2 ответа

Да, это запрещено. Вы не первый, кому пришла в голову эта вполне логичная идея. На мой взгляд, это одна из очевидных «ошибок» / «упущений» в спецификации указателей на члены в C ++, но, очевидно, комитет не заинтересован в дальнейшей разработке спецификации указателей на члены (как и случай с большинством «низкоуровневых» языковых функций)

Обратите внимание, что все необходимое для реализации этой функции уже есть в языке. Указатель на член-данные-члена ничем не отличается от указателя на непосредственный член-данные. Единственное, чего не хватает, - это синтаксиса для инициализации такого указателя. Однако комитет явно не заинтересован во введении такого синтаксиса.

С чисто формальной логической точки зрения, это должно было быть разрешено в 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 ++.

Поскольку все члены (непосредственные и члены членов) в конечном итоге размещаются в памяти последовательно, члены членов также могут быть идентифицированы по определенному значению смещения. Это то, что я имею в виду, когда говорю, что внутренняя работа этой функции уже полностью реализована, все, что требуется, это синтаксис инициализации.

В языке C эта функциональность эмулируется явными смещениями, полученными с помощью стандартного offsetof макрос. А в CI можно получить offsetof (Outer, inner.i) и offsetof (Outer, j [2]) . К сожалению, эта возможность не отражена в указателях-элементах-данных C ++.

Поскольку все члены (непосредственные и члены членов) в конечном итоге размещаются в памяти последовательно, члены членов также могут быть идентифицированы по определенному значению смещения. Это то, что я имею в виду, когда говорю, что внутренняя работа этой функции уже полностью реализована, все, что требуется, это синтаксис инициализации.

В языке C эта функциональность эмулируется явными смещениями, полученными с помощью стандартного offsetof макрос. А в CI можно получить offsetof (Outer, inner.i) и offsetof (Outer, j [2]) . К сожалению, эта возможность не отражена в указателях-элементах-данных C ++.

Это то, что я имею в виду, когда говорю, что внутренняя работа этой функции уже полностью реализована, все, что требуется, это синтаксис инициализации.

В языке C эта функциональность эмулируется явными смещениями, полученными с помощью стандартного offsetof макрос. А в CI можно получить offsetof (Outer, inner.i) и offsetof (Outer, j [2]) . К сожалению, эта возможность не отражена в указателях-элементах-данных C ++.

Это то, что я имею в виду, когда говорю, что внутренняя работа этой функции уже полностью реализована, все, что требуется, - это синтаксис инициализации.

В языке C эта функциональность эмулируется явными смещениями, полученными с помощью стандартного offsetof макрос. А в CI можно получить offsetof (Outer, inner.i) и offsetof (Outer, j [2]) . К сожалению, эта возможность не отражена в указателях-элементах-данных C ++.

19
ответ дан 30 November 2019 в 07:08
поделиться

InnerStruct, о котором вы заботитесь, содержится в экземпляре MyStruct, но это не влияет на то, как вы получаете указатель на член InnerStruct.

bool InnerStruct::* toto2 = &InnerStruct::c;

Edit: Rereading на ваш вопрос, я предполагаю, что вы хотите определить указатель на член внешней структуры и указать, чтобы он указывал непосредственно на член внутренней структуры. Это просто недопустимо. Чтобы перейти к члену внутренней структуры, которая содержится во внешней структуре, вам нужно будет создать указатель на внутреннюю структуру, а затем на ее член. Чтобы использовать его, вы должны разыменовать оба указателя на члены:

// Pointer to inner member of MyStruct:
InnerStruct MyStruct::* toto = &MyStruct::inner;

// Pointer to c member of InnerStruct:
bool InnerStruct::* toto2 = &InnerStruct::c;

// Dereference both to get to the actual bool:
bool x = mystruct.*toto.*toto2;
19
ответ дан 30 November 2019 в 07:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: