у меня есть вложенная структура, и я хотел бы иметь указатель на участника на одного из вложенного участника:
действительно ли это законно?
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;
Да, это запрещено. Вы не первый, кому пришла в голову эта вполне логичная идея. На мой взгляд, это одна из очевидных «ошибок» / «упущений» в спецификации указателей на члены в 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 ++.
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;