Subject: Re: [boost] [move] [range] move algorithm (was: interest: the pass-by-value...)
From: Neil Groves (neil_at_[hidden])
Date: 2014-02-18 18:47:00
On Tue, Feb 18, 2014 at 6:30 PM, Neil Groves <neil_at_[hidden]>wrote:
> On Tue, Feb 18, 2014 at 5:32 PM, Eric Niebler <eniebler_at_[hidden]> wrote:
>> On 02/18/2014 09:16 AM, Adam Wulkiewicz wrote:
>> > Hi Eric,
>> > Eric Niebler wrote:
>> >> On 02/15/2014 02:17 PM, Adam Wulkiewicz wrote:
>> >>> There is already boost::move_iterator in Boost.Move
>> >> Please make sure that move iterators and ranges are Input and not
>> >> anything else, regardless of what the standard says. The standard is
>> >> dangerously wrong in this regard.
>> > Thanks for the advice. It's because the user might by mistake go through
>> > some elements more than once which would result in some number of moves
>> > from the same element or do you have something more surprising in mind?
>> That's it precisely. And using move iterators in standard algorithms
>> that assume anything other than Input is pretty much guaranteed to make
>> you very unhappy.
> I agree that many scenarios would end in much unhappiness! I disagree that
> unhappiness is pretty much guaranteed. I believe there are valid scenarios
> that would be broken by increasing the requirements to demand single-pass
> traversal. The most common case that I think would be broken in my own code
> is where I am using a random-access iterator to stride. Currently I can
> stride and move ever n-th element. Isn't this perfectly acceptable? I'm not
> convinced we should break any valid use-cases to detect more errors.
> Perhaps we can find a better mechanism to detect double moves in debug
> builds instead?
>> > Unfortunately the boost::move_iterator follows the standard here. And
>> > since it's already in Boost it probably shouldn't be changed to ensure
>> > backward compatibility. We could of course implement different one and
>> > use it in Boost.Range but I'm not sure if this is a good idea. Should we
>> > have two different move_iterators in Boost?
>> I take a hard stand on this. A Forward move iterator is totally broken.
>> I have *no* sympathy for people who are using move iterators where
>> Forward is needed. Their code is buggy. We should change
>> boost::move_iterator and help people find their bugs. I have zero
>> compunction about doing this.
> If my previous paragraph is correct I believe we should not break working
> user code. Under my current understanding I don't think multiple (and
> therefore invalid) moves should be prevented by increasing the limits of
> the traversal. I think that the problem is a multiple moves and this can
> and should be dealt with directly instead. I wonder if the standard is
> liberal in the traversal requirements for similar reasons?
> I'm conscious that I could easily be misunderstanding some information and
> therefore my chain of reasoning may be broken.
I apologize for missing this section in my previous post. This is a
response to my own post. This is the standard section referring to moved
types that appears relevant:
*22.214.171.124 Moved-from state of library types
Objects of types defined in the C++ standard library may be moved from
(12.8). Move operations may be explicitly specified or implicitly
generated. Unless otherwise specified, such moved-from objects shall be
placed in a valid but unspecified state.
To me this indicates that I may have types where my "moved from" object is
valid and in a specified state. I extrapolate from this that therefore it
may be valid to move from the same object multiple times. I see no reason
why I should not implement a pimpl idiom where the moved-from object has
the pointer assigned to null and have valid multiple move operations from
the same type.
I therefore think there are a number of reasons to strongly disagree with
the notion that a move iterator must be an Input Iterator.