簡體   English   中英

反轉指向成員的指針(即獲取包含結構的地址)

[英]Invert pointer to member (i.e. get the address of the containing struct)

我有一個結構(成員),只能用作其他某些結構(容器)中的數據成員。 按照約定,成員的名稱始終為m。 成員是否有可靠的方法來獲取包含結構的地址?

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

struct Container
{
   Member<Container> m;
};

我希望使用指向成員&Container::m的指針可能有助於從Member對象本身的地址進行回算?

不,您不能這樣做。 您可以確定Containerm的偏移量,並執行指針算法來猜測Container的結果地址,但這將是:

  • 不可靠
  • 容易發生災難性錯誤
  • UB(因此可能會導致症狀,包括時間旅行- 不,嚴重!

如果您禁用了所有優化功能,那么它在某些平台上可能會始終如一地工作,但請不要這么做。

將指向Container的指針/引用傳遞到Member<Container>的構造函數中(添加一個之后),或者進一步重新考慮您的設計。 為什么成員需要知道封裝它的對象? 這幾乎總是錯誤的(盡管有一些可以通過的用例)。

不確定“可靠”,不應該鼓勵這種黑客行為,但是以下內容應該為您提供一個良好的起點:

#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;
}

我添加了一些成員,以便m具有實際的非零偏移量進行測試,但它也適用於零偏移量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM