User defined type and foreach

Tony tonytdominguez at aol.com
Fri Nov 17 03:15:12 UTC 2017


On Friday, 17 November 2017 at 01:16:38 UTC, H. S. Teoh wrote:

>
> It should be .empty, .popFront, and .front, not .pop.
>
> Also, these methods are *range* primitives, and over time, we 
> have come to a consensus that generally speaking, it's a bad 
> idea to conflate containers with ranges over containers.  The 
> main thing is that iterating over a range is supposed to 
> consume it, which is usually not what you want with a container.
>
> The usual idiom is to separate the two concepts, and have the 
> container provide a mechanism for returning a range over its 
> contents, usually via .opIndex with no arguments, or .opSlice. 
> Then you would just write:
>
> 	foreach (e; myContainer[]) { // [] calls .opIndex/.opSlice
> 		...
> 	}
>
> Unfortunately, built-in arrays, which are also ranges, are one 
> exception to this rule that, due to their ubiquity in D, also 
> serve to mislead newcomers to D about when/where range 
> primitives should be implemented. Generally speaking, built-in 
> arrays should not be considered exemplary in this respect, but 
> rather should be understood as exceptions.  The general 
> convention is to separate your containers from ranges over its 
> contents, and to provide .opIndex / .opSlice that constructs a 
> range over the container when needed.
>
> The other consideration is that if you don't really need range 
> functionality, i.e., the only thing you want to do with your 
> container is to put it in a foreach loop, then you can sidestep 
> this whole mess and just implement .opApply for your container 
> and call it a day.  Of course, then you won't be able to use 
> generic algorithms like those in std.algorithm with your 
> container, but if you didn't intend to anyway, it's not a big 
> deal.
>
>
> T

Thanks T! Good information, especially "iterating over a range is 
supposed to consume it". I have been reading 
dlang.org->Documentation->Language Reference, but  should have 
also read dlang.org->Dlang-Tour->Ranges. Although that page makes 
a distinction about "range consumption" with regard to a 
"reference type" or a "value type" and it isn't clear to me why 
there would be a difference.


More information about the Digitalmars-d-learn mailing list