【问题标题】:How to get a member pointer from a class pointer and plain pointer to member in C++?如何从类指针和指向 C++ 成员的普通指针中获取成员指针?
【发布时间】:2023-09-28 21:59:01
【问题描述】:

我可以像示例中那样获得指向对象实例成员的普通指针。反方向怎么办?

struct S {
    int i;
};

// We have a pointer to an instance of S and an int member pointer in S.
// This function returns a pointer to the pointer member in the pointed object.
int* from_mptr(S* s, int S::* mp) {
    return &(s->*mp);
}

// How to implement this?
// We have the object pointer and a pointer to a member of this object instance.
// I would like to have a member pointer from these.
int S::* to_mptr(S* s, int* p) {
    // return ???
}

从技术上讲,它必须是可能的,因为实例上的对象和成员之间的区别在于成员指针。虽然我不知道正确的语法。

【问题讨论】:

  • 您的直觉是错误的 - 没有办法获取指针并找出它指向的成员(如果有的话),并且除了应用 @987654324 之外没有办法创建指向成员的指针@给班级成员。这看起来有点像XY problem。你最终想要完成什么?
  • 没那么简单。看看offsetof。即使这只能通过一些编译器魔法和 afaik 来实现,它也不能用于获取指向成员的指针
  • 用例是什么?您有一个实例的int*i 并且想要访问其他实例的i?也许有不同的方式来实现你的目标
  • 您基本上需要有一个存在的每个int S::* 指针的列表,并比较p 是否是用s 取消引用的指针之一。最终,如果 C++ 获得静态反射,则无需手动实现这样的列表就可以实现它。
  • 是否保证 int *p 是一个指针,指向struct S 的某个实例中的int 成员?

标签: c++ member-pointers data-member-pointers


【解决方案1】:

遍历结构中与指针具有相同类型的每个成员,并将其地址与提供的指针进行比较 - 如果它们匹配,则返回适当的成员指针。对于呈现的玩具示例:

int S::* to_mptr(S* s, int* p) {
    if (&s->i == p) {
       return &S::i;
    }
    return nullptr;
}

【讨论】: