
On Wed, Jan 30, 2013 at 1:40 AM, Joel de Guzman <djowel@gmail.com> wrote:
On 1/30/13 5:00 AM, Paul Smith wrote:
On Tue, Jan 29, 2013 at 7:25 PM, Jeffrey Lee Hellrung, Jr.
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 :-)
Ok, let's just agree to disagree then and leave it at that.
Listen, Joel, I'll say this once more - I'm not trying to annoy you. This discussion isn't about you or me, it's about variant, and it also seems to be about move semantics in general. I agree to disagree with you, but I still want to understand the view you represent for my own sake, whoever cares to explain it to me. What the language semantics are designed for, what the standard library guarantees and effectively requires, and what the committee seem to advocate for, are conservative move-semantics - ones that require that a moved-from object maintains its invariants (in the case of the library - its requirements). On the other hand we have destructive move-semantics, for the sake of this discussion let's define them as the ones that merely require the moved-from object to remain destructible and assignable. If this is where I'm wrong - I'd love to be shown otherwise, either by giving me a standard citation or a reference to a WG paper that shows it, or by addressing the ones I gave and explaining to me what did I misinterpret. Currently, recursive_wrapper has the fact that it always holds a value as an invariant, or equivalently in the context of variant, variant has a never-empty guarantee and a variant that contains a recursive_wrapper<T> behaves as if it contained a T. Now we have a problem, because nulling recursive_wrapper's pointer, even though it does the trick for destructive move-semantics, breaks these invariants. This problem is in fact not uqniue to variant or recursive_wrapper specifically. If our universal solution to this problem is going to be to introduce an artifical post-move state and have it as an anti-precondition to anything but assignemnt and destruction, then what's the point in having conservative move-semantics in the first place? Destructive move-semantics is what we end up with in practice. We'd be much better off by saying that moved-from objects can break their usual invariants than by having to weaken those invariants. This is my break-down of the situtation. If anyone disagrees with any of this - I'd love to hear why. -- Paul Smith