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
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.
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);
}
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.