Offset from member pointer without temporary instance

后端 未结 3 730
故里飘歌
故里飘歌 2021-02-05 22:21

I would like to get the offset of a standard layout member variable when provided with a poiner to that variable. I cannot use offsetof since I have a pointer and n

相关标签:
3条回答
  • 2021-02-05 23:03

    So how about:

    template<class T>
    struct {
        ptrdiff_t get_offset( int (T::*mem) )
        {
            return 
            ( &reinterpret_cast<const char&>( 
                reinterpret_cast<const T*>( 1 )->*mem ) 
              - reinterpret_cast<const char*>( 1 )      );
        }
    };
    

    ..?

    This avoids both using a dummy AND dereferencing null. It works on all the compilers I've tried. The cast to char reference and then take the address (rather than take the address and then cast to char pointer) may seem unusual but it avoids a warning/error on some compilers.

    0 讨论(0)
  • 2021-02-05 23:05

    I'm afraid that no standard-compliant solution which satisfies OP requirements exists.

    I can give a couple of non-compliant ones.

    template<class T>
      size_t get_offset( int (T::*mem) )
        {
        return reinterpret_cast<char*>(&(((T*)nullptr)->*mem))-reinterpret_cast<char*>(nullptr);
        }
    

    It's funny, but the following works in VC2010, making use of offsetof being a macro.

    template<class T>
      size_t get_offset( int (T::*mem) )
        {
        return offsetof(T, *mem);
        }
    
    0 讨论(0)
  • 2021-02-05 23:11

    How about:

    template<class T>
    struct {
      ptrdiff_t get_offset( int (T::*mem) )
      {
        union {
          int used;
          T unused;
        } dummy;
        return reinterpret_cast<char*>(&(dummy.unused.*mem)) 
          - reinterpret_cast<char*>(&dummy.unused);
      }
    };
    

    The address of a union member doesn't depend on the union member being constructed. Works already in C++03, but then only for PODs.

    0 讨论(0)
提交回复
热议问题