Passing iterators into functions
Mike Parker
aldacron at gmail.com
Thu Jun 25 08:57:20 UTC 2020
On Thursday, 25 June 2020 at 03:35:00 UTC, repr-man wrote:
>
> This seems to have to do with the fact that all iterators
> return their own unique type. Could someone help me understand
> the reason behind this design and how to remedy my situation?
Ranges conform to well-defined interfaces. Given that the
algorithms in Phobos are templates and use structs rather than
classes, this means the interfaces are checked at compile time
(see the `is*` templates in std.range.primitives [1]). It also
means that there is no concrete range "type" returned by these
functions. That's why all of them return `auto` instead of a
specific type. You never need to know the specific type of a
range.
Arrays are ranges only because of the free-function
implementation of the range interfaces in std.range.primitives
which all take an array as the first argument so that they may be
called using UFCS in any templated range algorithm.
So when you input an array to a range algorithm, the algorithm
has no idea it has an array. It just calls R.emtpy, R.front,
etc., without ever caring what the actual type is. And you can
chain them because each algorithm wraps the input range with
custom range type that actually implements the algorithm (in
e.g., `popFront`--that's also why ranges are lazy), and that's
what is returned. In a chain of function calls, popFront is
called on the outermost range, which calls popFront on its
wrapped range, which calls popFront on its wrapped range, etc. So
if you append std.array.array to the end of the chain, it will
kick off execution of the whole chain of calls by making the
first call to popFront in order to copy the result into a new
array.
Chapter 6, "Understanding Ranges", from "Learning D" is available
freely online [2]. You should give it a read.
[1] https://dlang.org/phobos/std_range_primitives.html
[2] https://hub.packtpub.com/understanding-ranges/
More information about the Digitalmars-d-learn
mailing list