Taking offset of a data member is as easy as this:
#define MEMBER_OFFSET(Type, Member) \
((unsigned long)(((char *)&((Type *)0)->Member) - (char *)0));
I want to make this a constant compile-time expression (or use type traits). For example, to use it to implement SFINAE based solutions using member offsets, use it static assertions etc.
UPDATE: The question is - how to make it a compile-time expression. Not whether it works with POD types, or is there a standard macro in C library etc.
Though I can't get what your compiler is, the following code can be compiled by VC8, ideone(gcc-4.3.4), and Comeau online:
struct A { int i; };
template< size_t > struct S;
int main() {
S< offsetof( A, i ) > *p;
}
Gcc has __offsetof__
extension.
VC seems to have a capability to take a non-compile-time constant for a template
argument strangely.
As for Comeau, I have no idea about the internal of Comeau's offsetof
unfortunately.
Incidentally, though this won't answer your question directly, as for SFINAE purpose, since a member pointer constant can be used as a template argument and you can specialize on it, you can write as the following:
struct A {
int i, j;
};
template< int A::* > struct S;
template<> struct S< &A::i > { static char const value = 'i'; };
template<> struct S< &A::j > { static char const value = 'j'; };
int main() {
cout<< S< &A::i >::value <<endl;
cout<< S< &A::j >::value <<endl;
}
Hope this helps.