是指向-"内部结构"会员被禁止?

2021-12-13 00:00:00 pointers c++

我有一个嵌套结构,我想要一个指向嵌套成员之一的成员指针:

i have a nested struct and i'd like to have a pointer-to-member to one of the nested member:

合法吗?

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它是这样使用的:

Here are some details Yes it is &MyStruct::b and not mystruct::b; The code is from a custom RTTI/Property system. For each specified class we keep an array of "Property", including a Ptr-to-member It is used like this:

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

推荐答案

是的,这是被禁止的.您不是第一个提出这个完全合乎逻辑的想法的人.在我看来,这是 C++ 中指向成员的指针规范中明显的错误"/遗漏"之一,但显然委员会对进一步开发指向成员的指针的规范没有兴趣(就像是大多数低级"语言功能的情况).

Yes, it is forbidden. You are not the first to come up with this perfectly logical idea. In my opinion this is one of the obvious "bugs"/"omissions" in the specification of pointers-to-members in C++, but apparently the committee has no interest in developing the specification of pointers-to-members any further (as is the case with most of the "low-level" language features).

请注意,在语言中实现该功能所需的一切都已经存在.指向成员数据成员的指针与指向直接数据成员的指针没有任何区别.唯一缺少的是初始化此类指针的语法.然而,委员会显然对引入这样的语法不感兴趣.

Note that everything necessary to implement the feature in already there, in the language. A pointer to a-data-member-of-a-member is in no way different from a pointer to an immediate data member. The only thing that's missing is the syntax to initialize such a pointer. However, the committee is apparently not interested in introducing such a syntax.

从纯形式逻辑的角度来看,这在 C++ 中应该是允许的

From the pure formal logic point of view, this should have been allowed in 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

指针到数据成员的典型实现只不过是成员从封闭对象开头的字节偏移量.由于所有成员(立即数和成员的成员)最终在内存中按顺序排列,因此成员的成员也可以通过特定的偏移值来标识.当我说这个功能的内部工作已经完全实现时,这就是我的意思,所需要的只是初始化语法.

A typical implementation of pointer-to-data-member is nothing more than just an byte-offset of the member from the beginning of the enclosing object. Since all members (immediate and members of members) are ultimately laid out sequentially in memory, members of members can also be identified by a specific offset value. This is what I mean when I say that the inner workings of this feature are already fully implemented, all that is needed is the initialization syntax.

在 C 语言中,此功能由通过标准 offsetof 宏获得的显式偏移量来模拟.在 C 中我可以获得 offsetof(Outer,inner.i)offsetof(Outer, j[2]).不幸的是,此功能并未反映在 C++ 指向数据成员的指针中.

In C language this functionality is emulated by explicit offsets obtained through the standard offsetof macro. And in C I can obtain offsetof(Outer, inner.i) and offsetof(Outer, j[2]). Unfortunately, this capability is not reflected in C++ pointers-to-data-members.

相关文章