Is there any reason to use non-ref foreach?
bauss
jj_1337 at live.dk
Fri Aug 31 12:52:17 UTC 2018
On Friday, 31 August 2018 at 09:59:20 UTC, Dukc wrote:
> For me, it seems that for generality you should always add ref
> into foreach loop variable. The reason is this:
>
> import std.experimental.all;
>
> struct NoCopies
> { @disable this(this);
> int payload;
> }
>
> void main()
> { auto range = new NoCopies[20];
> foreach(const ref el; range) el.payload.writeln;
> }
>
> Without ref qualifier in el, this won't work because it would
> make a copy. Unlike ref as a function argument, it does not
> enforce refness:
>
> import std.experimental.all;
>
> void main()
> { auto range = iota(20).map!(x => x + 2);
> foreach(const ref el; range) el.writeln;
> }
>
> This compiles, even though range elements are rvalues.
>
> This seems to imply, for me, that for generality one should
> always use ref in foreach loop variables. If the vairable has
> to be guarded against changes, it should const ref, not
> unqualified.
>
> But considering unqualified is the default, I am probably
> missing something here. Performance?
It makes sense in your simplified examples, but in practice it
doesn't, because it will depend on each situation, what type of
data you're enumerating etc.
And I bet you there are some gotchas using just ref.
In reality you're micro-optimizing something that doesn't require
it.
Remember that basically the difference is this.
foreach (i; values) {
...
}
for (int _ = 0; _ < values; _++)
{
auto i = values[_];
...
}
VS
foreach (ref i; values) {
...
}
for (int _ = 0; _ < values; _++)
{
auto i = &values[_];
...
}
So basically ... Instead of copying the value, you're just
copying the address.
I can't see the benefit other than added complexity.
More information about the Digitalmars-d-learn
mailing list