Exceptional coding style
monarch_dodra
monarchdodra at gmail.com
Tue Jan 15 14:10:22 PST 2013
On Tuesday, 15 January 2013 at 21:26:14 UTC, Stewart Gordon wrote:
> On 15/01/2013 10:20, FG wrote:
> <snip>
>> All thanks to a terrible naming decision...
>> It's not remove but move_to_end. Why call it remove?
It HAS to do this because there is a separation of iteration
primitives and container. An iterator cannot (by itself)
spontaneously remove a value from a container.
FWI, D has the EXACT same semantics:
1) Use std.algorithm.remove to bump the unwanted values to the
end of the range, receiving in return a range of said elements.
2) Pass said range to std.container.remove to remove(erase) the
elements from the container itself.
It may not be intuitive at first, but it makes perfect sense, and
is (very) good design. It keeps orthogonal concepts orthogonal.
the erase remove idiom always surprises the first time around,
but quickly becomes natural. It's a tried and tested idiom.
> It doesn't necessarily move them to the end, going by
> http://www.cplusplus.com/reference/algorithm/remove/
> "The relative order of the elements not removed is preserved,
> while the elements past the new end of range are still valid,
> although with unspecified values."
>
> Just looking at the sample implementation there....
>
> if (!(*first == value)) *result++ = *first;
>
> places each non-removed value in its place in the final state
> of the container, but doesn't do anything particular with the
> value where it was taken from. In a C++11 implementation, I
> would expect it to become
>
> if (!(*first == value)) *result++ = std::move(*first);
>
> Stewart.
Note that: "The behavior of this function template is *equivalent
to*"
In no way does this mean this is the actual implementation.
Besides, the actual definition as decribed in n3242 is:
//----
Requires: The type of *first shall satisfy the MoveAssignable
requirements
Effects: Eliminates all the elements referred to by iterator i in
the range [first,last) for which the following corresponding
conditions hold: *i == value, pred(*i) != false.
Returns: The end of the resulting range.
//----
The "MoveAssignable" implies what you just said.
More information about the Digitalmars-d
mailing list