Dave wrote:
Hello all,
For purposes of understanding the language better, I tried to determine the
offset of a struct member by using pointers to members (instead of something
such as the offsetof macro). However, if I understand correctly, this may
not be done portably. If I try to print a pointer to member, it just
converts to bool and I always get 1 (unless it's a null pointer to member).
There are no conversions from pointer to member to an integral type, so I
think I'm out of luck. Of course, I could hack the underlying
representation on my platform, but I want to be Standard-compliant...
Does anybody know of a way I can do what I want, or is my analysis correct
that it cannot be done portably?
It's ugly but this should work.
template <typename T, typename V>
inline int MemberOffsetOf( V T::* v )
{
return ((int)&((( A* )0)->*v));
}
As for a compile-time version, you can't do it because you need to use
the "&" operator (address of) and this is apparently illegal in a
constant expression.
This is somthing like what it would look like for a compile-time
constant had the "&" operator been allowed.
template <typename T, typename V>
struct ClassValue
{
typedef T classtype;
typedef V valuetype;
template < V T::* P >
struct DoOffset
{
// & illegal here - sniff sniff ...
static const int offset = ( (int) & ( ( (T*) 0)->*P ) );
};
template <V T::* P>
char ( & SizeofThing() )[ DoOffset<P>::offset ];
};
template <typename T, typename V>
ClassValue< T, V > SizeofHelper( V T::* );
#define MemberOffsetOf( Member ) \
sizeof( SizeofHelper( Member ).SizeofThing< Member >() )