std.range.interfaces : InputRange moveFront
Ali Çehreli
acehreli at yahoo.com
Fri Dec 1 18:33:09 UTC 2017
On 12/01/2017 07:21 AM, Steven Schveighoffer wrote:
> On 12/1/17 4:29 AM, Johan Engelen wrote:
>> (Also, I would expect "popFront" to return the element popped, but it
>> doesn't, OK...
>
> pop removes the front element, but if getting the front element is
> expensive (say if it's a map with a complex lambda function), you don't
> want to execute that just so you can return it to someone who doesn't
> care. This is why front and popFront are separate.
Yet, we're told that compilers are pretty good at eliminating that
unused copy especially for function templates where all code is visible.
[I have second thoughts about what I write below. Bear with me...]
I think the actual reason is one that I learned in C++ circles which I
will never forget as I was lurking on comp.lang.c++.moderated as the
whole exception safety was discussed, finally solved, and popularized by
Herb Sutter.
So, even thoug exception safety is not a common topic of D community,
the real reason for why popFront() does not return the element is for
strong exception safety guarantee. Otherwise, it's not possible to
recover from a post-blit that may throw. The reason is, popFront() must
change the structure of the container *before* the returned object must
be copied. When the copying throws, then the element is already lost
from the container.
However, there are two potential solutions that I think of:
- D could move the element out; so no post-blit would be necessary.
However, as we see in moveFront()'s source code, it might have to call a
provided moveFront() and that might throw:
static if (is(typeof(&r.moveFront)))
{
return r.moveFront();
}
- D has scope(failure) which could revert the container's state but I
don't think it's possible for all containers. (And I should have said
"ranges".)
Regardless, separating front() from popFront() is preferable due to
cohesion: fewer responsibilities per function, especially such low level
ones.
Ali
More information about the Digitalmars-d-learn
mailing list