Binding rvalues to ref [WAS: I close BIP27. I won't be pursuing BIPs anymore]

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Fri Oct 21 03:08:05 PDT 2016


On Thursday, October 20, 2016 23:18:14 Nicholas Wilson via Digitalmars-d 
wrote:
> On Thursday, 20 October 2016 at 01:04:35 UTC, Jonathan M Davis
>
> wrote:
> > The transitivity of const shoot stuff in the foot pretty
> > thoroughly in a number of cases. A prime example would be
> > ranges, because they have to be mutated to be iterated over. If
> > the function actually took a range directly, you wouldn't
> > bother with const ref, but it could be an object that contains
> > a range, and because you can't normally get a tail-const range
> > from a const range (aside from dynamic arrays), it can become
> > quite difficult to actually iterate over the range. e.g.
> >
> > auto foo(ref const(Bar) bar)
> > {
> >
> >     auto range = bar.getSomeRange();
> >     ...
> >
> > }
>
> Is it legal to `.save` a const range, and then use it (provided
> it does not mutate any object reachable from bar)?

Not really. isForwardRange requires that save return _exactly_ the same type
as the range. So, it really can't work as a const function (and
const(MyRangeType) will never pass isInputRange or isFowardRange, because
popFront won't compile). You _can_ declare an overload of save that's const
and returns something different, but then it's not actually part of the
range API, and you can't rely on it working. At that point, you might as
well make up your own function, since what you're doing is non-standand
anyway.

Regardless of all that though, it's not always even possible for a range to
have a function that returns a tail-const version of the range because of
how the internals of the range work. So, even if we had a standard way to
deal with that, it couldn't work in all cases, and really, it would have to
be dealt with separately from traits like isForwardRange. Arguably, to match
arrays, we should be defining an opSlice for ranges which returns a
tail-const version of the range (and then we could have a trait like
hasTailConstSlicing), but that's not currently part of the range API, and
it's actually pretty hard to define even for simple ranges (e.g. you have to
use static if carefully to avoid recursive template instantiations).

So, the best way to handle this is very much an open question. For now, the
reality of the matter is that there is no standard way for const ranges to
work.

- Jonathan M Davis



More information about the Digitalmars-d mailing list