Re: Common base class, reinterpret_cast, and aliasing
On Mar 27, 3:00 pm, guillaume.melqui...@gmail.com wrote:
Thanks, that's a really interesting approach; it didn't occur to me to
rely on multiple inheritance. Unfortunately, it's unpractical for my
needs. I'm trying to show that C++ is powerful enough to emulate some
techniques available in modern programming languages (modern as in
almost experimental). More particularly, the example was extracted
from a case of data invariance under type convertibility.
Guillaume
What you seem to be trying to do is "Structural Typing" like ML or
Haskell. http://en.wikipedia.org/wiki/Structural_type_system . C++
uses a "Nominative" type system. Structural typing more or less
depends on the data layout of the object, while the nominative more or
less depends on what you declare the object to be, regardless of how
it is actually laid out in memory.
So what you need is a way to declare that the data layout of two
otherwise unrelated declarations are the same. Of course you could
just write a ML interpreter in C++, but I guess that is not the point
of this exersize.
I would start by exploring tr1::tuple, which is a library whose layout
and type are virtually synonymous. There are even "cons" and "cdr"
like functionality built in. You can get one implementation at
boost.org. Also pick up type_traits - this give you the tools to test
whether two types are the same -- which with tuple means that the
structure is the same as well.
Then given a good compile time checker (also available at boost) try
this:
typedef tr1::tuple<X,Y,Z> layout_t;
struct A :layout_t{
typedef layout_t layout_type;
/*functions, no data*/};
struct B :layout_t{
typedef layout_t layout_type;
/*functions, no data*/};
// this will NOT be true for virtual funny business
// or compilers that do not do EBCO, which you also need
STATIC_ASSERT(sizeof(A)==sizeof(layout_type));
STATIC_ASSERT(sizeof(B)==sizeof(layout_type));
template<class T,class F>
T& structural_cast(F &_f){
STATIC_ASSERT(tr1::is_same<T::layout_type,F::layout_type>::value);
return reinterpret_cast<T&>(_f);
}
These type of checks make sure that the reinterpret_cast does what you
think it will do. This is still not perfectly 100% by the book
standard, nor can it do an infinity of anything, but then again there
is no program that is or could.
Lance
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]