
David Abrahams wrote:
Joao Abecasis <jpabecasis@zmail.pt> writes:
David Abrahams wrote:
I think the question is whether it's ever desirable to break the current C++ invariant that no two objects of the same type will ever share an address **in generic code** -- that is, when you don't know anything about the assumptions that may be made by that type.
An alternative implementation is to privately inherit from the specified type for empty classes as compressed_pair does. This maintains the invariant but has the drawback that inheritance is visible in user code.
Yeah, the primary danger being unintentional overriding of virtual functions from the private base. I like the protection your idea provides. You could arrange a compressed_pair based on this design that still maintains the invariant. And then you could make it smart enough to aggregate other compressed_pairs without ever allocating two of the same type at the same address.
I think virtual classes are not an issue because they are not empty. There's always a pointer to vtable or something. Both compressed_member and compressed pair store non-empty types as regular variables and those keep the invariant at all times. The invariant is violated only with a mix of empty compressed_members and empty member variables.
For a generic compressed_tuple the private inheritance should not be a problem.
I'm not sure what you mean by that, sorry.
The motivation for writing compressed_member was to bring EBO to member variables in user code. Using private inheritance brings about some quirks, e.g. : struct A {}; struct B : compressed_member<A> { int something() { A a; } }; is illegal with private inheritance. It also interferes with overload resolution and is_base_and_derived. We'd have a "member" variable that shows up as a base everywhere. In a generic compressed_tuple library some of these are non-issues and the usefulness of compressed_pair stands for that. Regards, João