std.algorithm.iteration.each requires opApply to have ref elements?

Chris via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Sep 16 03:18:04 PDT 2016


On Thursday, 15 September 2016 at 18:23:14 UTC, Q. Schroll wrote:
> Why does it do that?
> And seemingly it does not require it for opApply with more than 
> two arguments.

Here's what the comment says:

https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d#L929

// opApply with >2 parameters. count the delegate args.
     // only works if it is not templated (otherwise we cannot 
count the args)
     void each(Iterable)(Iterable r)
         if (!isRangeIterable!Iterable && 
!isForeachIterable!Iterable &&
             __traits(compiles, 
Parameters!(Parameters!(r.opApply))))
     {
         auto dg(Parameters!(Parameters!(r.opApply)) params) {
             pred(params);
             return 0; // tells opApply to continue iteration
         }
         r.opApply(&dg);
}

Usually, if you change elements while iterating, you need to 
`ref` them. If you leave out `ref` the following loop will finish 
after 'd'. If you put in `ref` you have an infinite loop.

void main()
{
   import std.stdio : writefln;
   auto arr = ['a', 'b', 'c', 'd'];
   foreach (ref i, c; arr)
   {
     if (c == 'c')
     {
       --i;
       writefln("index = %d", i);
     }
   }
}


More information about the Digitalmars-d-learn mailing list