Boost logo

Boost :

Subject: Re: [boost] [variant] Please vote for behavior
From: Antony Polukhin (antoshkka_at_[hidden])
Date: 2013-01-30 05:58:10


2013/1/30 Joel de Guzman <djowel_at_[hidden]>:
> On 1/30/13 7:23 AM, Larry Evans wrote:
>
>>>> This discussion might be facilitated if Joel et al (sorry Joel, I don't
>>>> mean to pick on you, I just mean the group arguing for introducing this
>>>> "singular" post-move state) simply said "yes, we understand we're
>>>> making a
>>>> breaking change (by possibly introducing an additional state to variant
>>>> that violates the never-empty guarantee), but we still think it's the
>>>> most
>>>> practical approach to introduce efficient move semantics to variant".
>>>> I can
>>>> jive with that but I think Paul's concerned that you (again, as a
>>>> representative of the platform you're taking) don't appreciate that
>>>> this is
>>>> a breaking change to variant.
>>>
>>>
>>> No, Jeff, that is wrong. We are not violating the semantics to variant.
>>> It's not about variant. It's about recursive_wrapper. I think people are
>>> confused with this. The variant's never-empty guarantee still holds.
>>
>>
>> The page:
>>
>>
>>
>> http://www.boost.org/doc/libs/1_52_0/doc/html/variant/design.html#variant.design.never-empty
>>
>> says:
>>
>> variant may be viewed precisely as a union of exactly its bounded
>> types
>>
>> but having a singular-valued recursive_wrapper violates this view,
>> because there's no way you can dereference a singular-valued
>> recursive_wrapper to get at one of the bounded types.
>
>
> That is actually a good point. I didn't think of it that way, but yeah,
> I can appreciate that. So, I think I am inclined to agree with Jeff now.

I think that this example is perfect for showing the benefits of
nulled recursive wrapper.
Watch the hands:

union my_union {
    my_union u_; // Impossible to do
    int i_;
};

Because we can not use field of type my_union in my_union we need to wrap it:

union my_union {
    recursive_wrapper<my_union> u_; // Ok
    int i_;
};

Now we just need to decide, what a recursive_wrapper is! Is it behave
like a reference:

// # 1
union my_union {
    my_union& u_;
    int i_;
};

Or is it behave like a pointer:

// # 2
union my_union {
    unique_ptr<my_union> u_;
    int i_;
};

#1 is not what a recursive_wrapper is, because recursive_wrapper OWNS a value
#2 is much closer to functionality of recursive_wrapper

2013/1/28 Joel de Guzman <djowel_at_[hidden]>:
> (BTW, who is the current maintainer of variant? I don't see Itay and
> Eric here in this list anymore. I've invested heavily on variant and
> I am willing to be a maintainer of variant or be a co-maintainer with
> Antony Polukhin)

Have not seen them either.
I also invested heavily on variant, so I can keep an eye on it, but 4
eyes are much better! Especially because of me and Joel invested in
different parts of it :)

2013/1/30 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung_at_[hidden]>:
> - We can still get proper move semantics for variant in most use cases
> without ever violating the never-empty guarantee. This is only ever an
> issue for a recursive variant which is not default-constructible. The fix
> is easy: prepend your typelist with boost::blank.

It is already implemented (see 1.53 release notes for variant).
Variant with recursive_wrapper is default constructible if its first
parameter default constructible.

--
Best regards,
Antony Polukhin

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