Should the "front" range primitive be "const" ?

Steven Schveighoffer schveiguy at yahoo.com
Tue Jan 30 13:54:00 UTC 2018


On 1/29/18 8:20 PM, Jonathan M Davis wrote:
> On Tuesday, January 30, 2018 01:05:54 Drone1h via Digitalmars-d-learn wrote:
>> Hello all,
>>
>>
>>
>> I am trying to implement a ("struct template" ? what is the
>> correct word ?) range that just forwards its primitives ("empty",
>> "front", "popFront") to another range, possibly with some very
>> limited filtering/alteration, as std.range.Take (just to learn).
>>
>> Initially, the "front" member function (property) used to be
>> declared "const", but that was not accepted when the underlying
>> range (denoted "R" in the code below) was std.stdio.File.ByChunk
>> ("Error: mutable method std.stdio.File.ByChunk.front is not
>> callable using a const object").
>>
>> Is there any value in having the "front" range primitive declared
>> to be a "const"  member function ?
>>
>> And if so, is the following implementation okay ? Could it be
>> further simplified ?
>>
>>       struct Taker (R)
>>       {
>>           private R _r;
>>
>>           ...
>>
>>           static if (functionAttributes ! (R.front) &
>> FunctionAttribute.const_)
>>               public @property auto front () const { return
>> _r.front; }
>>           else
>>               public @property auto front ()       { return
>> _r.front; }
>>
>>           ...
>>       }
>>
>>
>>
>> Thank you respectfully !
>> Drone1h
> 
> If you want to put an attribute on it, inout is better, because then it will
> work with any constness, but in general, I'd suggest just avoiding the use
> of const or immutable altogether when dealing with ranges. front can return
> a const element, and that will happen if you use auto and whatever you're
> wrapping is const, but const ranges are utterly useless, because they can't
> be mutated and thus can't be iterated. As such, almost no code is ever going
> to have a range that is anything but mutable, which means that having front
> be anything but mutable is generally pointless.

Not necessarily. A main reason for const is to advertise "I'm not going 
to change your mutable data" on a function. So reading that front is 
const (or inout more appropriately) can assure you front makes this 
guarantee.

Yes, it also allows you to call on an immutable or const range, both of 
which are for the most part useless.

So I would say const ranges are useless, but const members of ranges 
provide some value.

That being said, const is viral, as is inout. So unfortunately if you 
*don't* mark your functions const or inout, then wrappers need to take 
this into account.

-Steve


More information about the Digitalmars-d-learn mailing list