I'm trying to implement my own range in D, and I'm having trouble with its .front()
method.
I need the return value to be by ref
.
If I make it const
, then the returned object will be a copy, which is not what I want.
If I don't make it const
, then I can't use .front
on a const
copy of my range at all.
How do I solve this?
struct MyRange(T)
{
T[] buf;
@property ref T front() { return this.buf[0]; } // No error, but not const
@property ref T front() const { return this.buf[0]; } // Errors
@property T front() const { return this.buf[0]; } // No error, but a copy
// Can't have all three
}
Try this:
struct MyRange(T)
{
T[] buf;
@property ref T front() { return this.buf[0]; }
@property ref const(T) front() const { return this.buf[0]; }
}
The problem in your example is that you made front
const but not the value being returned, and the compiler won't let you escape a mutable reference to const data like that.
Now, I would point out that in general, you shouldn't expect const ranges to work very well. By their very nature, they need to be mutable to iterate over them (since you can't call popFront
on a const range), so you're not going to be able to do much beyond using front
and empty
with a const range. The situation wouldn't be as bad if you could implicitly convert a const range to a tail-const range, but that only works with arrays, and no one has figured out a good way to do that with general ranges yet. So unfortunately, const ranges are essentially useless at this point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With