A couple of times I’ve run into the situation where a “new” C++ class is written to exactly match “legacy” C structures. At the edges where old code meets new code, you can cast one to the other in-place. For example, given a huge mess of data that includes
oldstruct s1;
you could write the line
newclass& s2= reinterpret_cast<newclass&>(s1);
because s2 is designed to exactly overlay s1. It might even derive from it, and just add member functions and friendlier accessors.
Another example I’ve seen is a class that contains nothing but a char* pointer member, that contains overloaded operators to replace the ancient str* functions. In particular, it has an operator==, so casting an array of char* to an array of that class allowed std::find to be used!
I don’t like the wild and unchecked use of reinterpret_cast, but I can see the point for these and think the idiom can be tamed. Basically, I want to write a cisam_cast that behaves like a reinterpret_cast but only for those conversions I’ve explicitly nominated as being cisam’s. CISAM is “compatible in structure and meaning”, and I avoid calling it “upgrade” because it works in either direction or sideways between different code bases’ definitions of the same wire data.
I’m thinking that I should be able to declare something like
template<> cisam<xxx,yyy> : std::tr1::true_type {};
to enable cisam_cast<xxx>(a_yyy) to have the same meaning as reinterpret_cast<xxx&>(a_yyy), etc. (foreshadowing hard question...)
Since it would be common to make a new class to wrap a primitive type or old struct, a shortcut would be to include a typedef yyy cisam; as a member of xxx.
Now I get around to my actual question: the “etc.” part above. Given that xxx and yyy are cisam-mates, I want to enable not only xxx to yyy and vice versa, but handle const and volatile qualified forms with correct cv-modifier carry-through, and handle pointers to them to any depth, which is complicated by the fact that there could be cv-qualifiers at any level.
In the earlier example, the original code was something like:
char* A[7]; char* val;
//...
Str* SA= reinterpret_cast<Str*>((char**)A);
and I would want
Str* SA= cisam_cast<Str*>(A);
to be accepted. Note that the cisam-ness is between (char*) and (Str), so there are a different number of stars on the before and the after.
So, how might I write the cisam_cast machinery to elaborate the basic cisam definitions into the full set of allowed casts?
Thanks,
--John
=====Begin Corporate Footer That I Can’t Do Anything About=====