Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-09-10 14:47:49


Joao Abecasis <jpabecasis_at_[hidden]> writes:

> David Abrahams wrote:
>
>>Joao Abecasis <jpabecasis_at_[hidden]> 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

Err, polymorphic classes, please.

> are not an issue because they are not empty. There's always a
> pointer to vtable or something.

Technically there does not have to be. An implementation could store
the information in a map indexed on the address of the object. That
said, no implementations do that. So I withdraw my concern.

> Both compressed_member and compressed pair store non-empty types as
> regular variables

Ahem; data members. ;-)

> and those keep the invariant at all times.

Right.

> 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>
    {};

>>>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.

??? why would private inheritance have an effect on the legality of
auto variables of any type??

> It also interferes with overload resolution and
> is_base_and_derived. We'd have a "member" variable that shows up as
> a base everywhere.

I agree that's a problem.

> In a generic compressed_tuple library some of these are non-issues
> and the usefulness of compressed_pair stands for that.

I see.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk