Re: aggregate casting
We all know dynamic/static cast - to travel along hierarchy.
Is there a good way to cast along aggregates?
e.g. fill the line with aggregate_cast
struct B {} ;
struct A {
int a1;
char a2;
// ...
B b;
// ...};
void foo(B*b)
{
// b is for sure member of A; need to calc A addr based on B addr.
A *a=/*aggregate_cast A.b*/ ; // elegant fill this missing line.
// do something with a;}
int main() {
A a;
B *b=&a.b;
foo(b);
}
Don't tell me to re-factor and use hierarchy instead of aggregating...
Hi, first, from the code, and form your last line comment, it looks
like you are doing something evil. If you cast B to A (A is B + a1 +
a2), what do you do if someone wants to use a1?
Anyway, without using reinterpret_cast, I guess what would suit your
needs is any of the two:
template< typename From, typename To, From To::* Offset >
To* aggregate_cast1( From* ptr )
{
void * voidOffs = &( static_cast<To*>(NULL) ->* Offset );
char * toOffs = static_cast<char*>( voidOffs );
ptrdiff_t diff = toOffs - static_cast<char*>(NULL);
void * begin = ptr;
void * x = static_cast<char*>(begin) - diff;
return static_cast<To*>( x );
}
template< typename From, typename To >
To* aggregate_cast2( From* ptr, From To::* Offset )
{
void * voidOffs = &( static_cast<To*>(NULL) ->* Offset );
char * toOffs = static_cast<char*>( voidOffs );
ptrdiff_t diff = toOffs - static_cast<char*>(NULL);
void * begin = ptr;
void * x = static_cast<char*>(begin) - diff;
return static_cast<To*>( x );
}
They can be used like this:
A *a = aggregate_cast1< B, A, &A::b >( b );
A *a = aggregate_cast2( b, &A::b );
However those solutions are evil and will only work under certain
conditions:
1. Struct A must be a POD: no virtual members, no virtual inheritance.
2. I am not sure how it works with different data alignments.
3. The only safe way to use thus converted pointer to A is to use its
member A::b.
Regards,
&rzej
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]