Re: Cast pointer to data member to integer type - legit?
Scott Lehman wrote:
When I first researched this, I read that pointers to data members were
just a byte offset which made sense, and I wanted to store that offset.
Using GCC 3.3 at the time, casting a pointer to a data member to a
offset_t or ptrdiff_t posed no issues and things worked great.
As it was already stated, the offsetof() macro from <cstddef> or <stddef.h>,
which is part of the Standard Library both in C++ and in C, should be used
for this. Note that in C++ it is only guaranteed to work with POD types.
However, if you really need to convert member pointers to offsets,
you can try the following function, for which one can imagine 2
different ways to implement it (I put them in a conditional
compilation directive):
template<typename ClassT, typename MemberT> inline
std::ptrdiff_t offset_off(MemberT ClassT::*memptr)
{
#if 0 // *** [1] ***
ClassT* pc = 0;
return reinterpret_cast<char*>(&(pc->*memptr)) - reinterpret_cast<char*>(pc);
#else // *** [2] ***
ClassT c;
return reinterpret_cast<char*>(&(c.*memptr)) - reinterpret_cast<char*>(&c);
#endif
}
Keep in mind that the way [1] relies on Undefined Behaviour,
thus it may work on some implementations and break on others
- especially in presence of multiple or virtual inheritance.
Way [2], while not suffering from this problem, has the
disadvantage of instantiating the class in question -
in particular it requires the presence of an accessible
default constructor.
So there is no 100% satisfying solution to your problem,
short of proposing an appropriate new feature to the Standard...
Falk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]