
David Abrahams wrote: [snip lots of embarassing comments :-) ]
The invariant is violated only with a mix of empty compressed_members and empty member variables.
Two empty compressed_members used as bases should be sufficient.
struct X : compressed_member<Base> , compressed_member<Derived> {};
Hmm... I completely missed those cases.
struct A {};
struct B : compressed_member<A> { int something() { A a; } };
is illegal with private inheritance.
??? why would private inheritance have an effect on the legality of auto variables of any type??
In the above example, A refers to a private inaccessible base of B. The scoping operator has to be used to instantiate A inside B. I'll have a new implementation later in the week. I'll have to drop the memberwise inheritance and head for something similar to a tuple. Possibly following the syntax suggestion of Joaquín López Muñoz. In the new implementation a structure is built to actually hold the data (either through public inheritance or as data members ;-) but it is never instantiated. The compiler ensures the invariants are maintained for that structure. Then I take its size and pad my compressed_tuple-wannabe with it. The same casting hacks, placement new, etc, are then used to avoid inheritance, provide a clean interface and maintain the initialization order. Only this new tuple will not be empty ever. And we'll have to live with that ;-). I took a look at Borland 5.5.1 and was able to come up with a few tricks that provide some form of EBO. But it's a no win situation because there is no way to actually determine it a given type is empty (with this compiler) to start with. For instance, empty classes take up the size of the base class. If the (final) base class is empty it's size is 8 but if it has a single char data member it's size will be 1! Regards, João Abecasis