2

我有一个结构(成员),它只能用作其他结构(容器)中的数据成员。按照惯例,成员的名称始终是 m。成员是否有可靠的方法来获取包含结构的地址?

template<typename Struct>
struct Member;
{
  const Struct& s = ??;
                    // this - &Struct::m
};

struct Container
{
   Member<Container> m;
};

我希望也许使用指向成员的指针&Container::m可能有助于从成员对象本身的地址计算回来?

4

2 回答 2

5

不,你不能这样做。您可以确定mwithin的偏移量Container并进行指针运算以猜测 的结果地址Container,但这将是:

  • 不可靠
  • 容易出现灾难性错误
  • UB(因此可能导致包括时间旅行在内的症状 -不,严重!

如果您禁用了所有优化,它可能会在一些平台上始终如一地工作,但真的,请不要这样做。

要么将指针/引用传递给ContainerMember<Container>构造函数(在添加一个之后),要么进一步重新考虑您的设计。为什么成员需要知道封装它的对象?这几乎总是错误的(尽管有一些可以接受的用例)。

于 2015-02-26T11:47:16.567 回答
1

Not sure about "reliable", and it's the sort of hack that shouldn't be encouraged, but the following should give you a good starting point:

#include <cassert>
#include <cstddef>
#include <type_traits>

template<typename Struct>
struct Member
{
    Struct const* s = (Struct*)&((char*)this)[-(int)offsetof(Struct, m)];
};

struct Container
{
    int abc;
    int def;

    Member<Container> m;
};



int main(int argc, char* argv[])
{
    assert(std::is_standard_layout<Container>::value);

    Container c;

    Container const *p1 = &c;
    Container const *p2 = c.m.s;

    bool test = p1 == p2;

    return 0;
}

I added some members so that m has an actual non zero offset for testing, but it also works for zero offset.

于 2015-02-26T11:43:11.487 回答