Subject: Re: [boost] [variant] Please vote for behavior
From: Paul Smith (pl.smith.mail_at_[hidden])
Date: 2013-01-29 16:00:07
On Tue, Jan 29, 2013 at 7:25 PM, Jeffrey Lee Hellrung, Jr.
> On Tue, Jan 29, 2013 at 7:12 AM, Paul Smith <pl.smith.mail_at_[hidden]> wrote:
>> On Mon, Jan 28, 2013 at 8:27 PM, Joel de Guzman <djowel_at_[hidden]> wrote:
>> > On 1/29/13 1:40 AM, Paul Smith wrote:
>> >>> I am also
>> >>> >not convinced that drawing from objects with "singular" values is
>> >>> >regardless if it's a pointer or not. I think it is you who's missing
>> >>> >the point because Iterators are likewise*not* pointers.
>> >> Okay, so replace "recursive_wrappers are not pointers" with
>> >> "recursive_wrappers are not iterators". How does it make it any
>> >> different? A singular value still doesn't fit in.
>> > The point is that iterators can have singular values. If iterators
>> > can have them, why can't any other object (have them)?
>> Why should any other object have them? Iterators are a generalization
>> of pointers and that's where they inherit their singular state from.
>> This has absolutely nothing to do with move-semantics, and that's
>> exactly why I say that such inferences, just like the NaN example, are
>> dangerously superficial. A moved-from iterator isn't singular just
>> like a default-constructed recursive_wrapper isn't. Different concepts
>> - different issues. The point I'm trying to make is that conceptually
>> recursive_wrappers don't have a value of their own. They have exactly
>> the same set of states as their underlying type. If this type has a
>> singular value, then and only then does a recursive wrapper around
>> this type has a singular value.
>> > IMO, ultimately,
>> > it's a matter of design. You may not agree with a recursive_wrapper
>> > being in a "singular" state after move, but that's just your preference.
>> Okay, I'm not sure what exactly we are disagreeing about anymore.
>> Do we agree that the move semantics we have in C++ are non-destructive
>> (I'm not asking whether you like it or not. At this point it's a fact
>> - not a preference)? If you agree with that, then you should
>> appreciate that it's like that for a reason, whether or not you agree
>> with that reason.
>> A moved-from object should remain in a valid state. You're suggesting
>> meeting this requirement by introducing a new (and yes, breaking)
>> state, let's bluntly call it the "invalid" state, and you don't see
>> what I'm talking about when I say that this is just missing the point?
>> Then there's really nothing more I can say...
>> > IMO, it's necessary for proxy-like objects that own and hold their
>> > subjects by pointer. It's not quite elegant, sure, but C++ is never
>> > elegant in many respects for the sake of high performance. I'd trade
>> > this quirk for the sake of efficiency any day.
>> That's a rant about how move semantics in C++ turned out (completely
>> intentionally) to be. This discussion isn't about that, it's about how
>> recursive_wrapper should behave under these semantics.
> 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.
I think this is about a little more than that, even though to be
honest, I'm not entirely sure what's the dispute is about too.
I think it's closer to what Edward Diener said:
The main issue seems to be simply this: are guarantees ( invariants )
for an object of a class meant to cover moved from objects of that class ?
All of the choices which you have specified, which popularly boils down
to II or III, involves this question. The choice of II answers No to the
question above while the choice of III answers Yes to the question above.
As absurd as it may sound right now, I think Joel's and mine opinions
are much closer than it seems. I like performance too, believe it or
not. And it's not just about performance, under non-destructive move
semantics there's an entire class of objects which is neither copyable
nor movable, and it becomes harder to give no-throw guarantees. I
definitely *do* want to be able to move recursive_wrapper by nulling
it's pointer. I think what we disagree on is how to get there :-)
-- Paul Smith