Look at this code:
struct S
{
int x;
int opApply(int delegate(ref int _x) dg) { return dg(x); }
}
void main()
{
S s;
foreach(ref a; s) ++a;
assert(s.x == 1);
}
If we replace the foreach loop with an each call, we would do:
s.each!"++a";
Except it doesn't work. When each accepts the iterable, it accepts it by value. It should accept it by reference (if it's a class, it could take the class reference by value). Otherwise, the point of using ref throughout each is kind of useless.
Comment #1 by jrdemail2000-dlang — 2016-10-09T21:25:24Z
An example that appears related:
void main()
{
import std.algorithm : each;
int[] dynamicArray = [1, 2, 3, 4, 5];
int[5] staticArray = [1, 2, 3, 4, 5];
dynamicArray.each!((ref x) => x++);
assert(dynamicArray == [2, 3, 4, 5, 6]); // modified
staticArray.each!((ref x) => x++);
assert(staticArray == [1, 2, 3, 4, 5]); // not modified
staticArray[].each!((ref x) => x++);
assert(staticArray == [2, 3, 4, 5, 6]); // modified
}
Using a ref parameter works in the range cases, but not the static array case (opApply).
Comment #2 by greeenify — 2016-12-23T02:04:46Z
> Except it doesn't work. When each accepts the iterable, it accepts it by value. It should accept it by reference (if it's a class, it could take the class reference by value). Otherwise, the point of using ref throughout each is kind of useless.
A simple solution with `auto ref` for Iterables:
https://github.com/dlang/phobos/pull/4991
Comment #3 by github-bugzilla — 2016-12-24T20:38:38Z
Is this supposed to work now ?
void main()
{
int[][] arr = void;
arr.length = 10;
version(all)
{
import std.algorithm.iteration : each;
arr.each!((ref a){a.length = 10; a[] = -1;});
}
else
{
foreach(ref a; arr)
{
a.length = 10;
a[] = -1;
}
}
}
Comment #7 by acehreli — 2022-06-10T20:12:00Z
(In reply to Basile-z from comment #6)
> Is this supposed to work now ?
>
>
> void main()
> {
> int[][] arr = void;
That is the problem. We can't use arr in any meaningful way because it already has garbage number of garbage elements.
> arr.length = 10;
It reduces the length to 10 but all the elements are garbage.
Comment #8 by robert.schadek — 2024-12-01T16:27:26Z