digitalmars.D.learn - Unexpected behaviour of foreach statement
- Arredondo (19/19) Mar 02 2018 Hi,
- rikki cattermole (3/11) Mar 02 2018 s/range/array/
- Nicholas Wilson (3/25) Mar 02 2018 try
- Arredondo (2/4) Mar 02 2018 This worked. Thank you!
- Jonathan M Davis (15/33) Mar 02 2018 foreach does not support indices for ranges, only arrays. When you have
- Arredondo (6/19) Mar 02 2018 I understand. I guess I was expecting the compiler to
- bauss (11/30) Mar 02 2018 What you want to do is call "enumerate" from "std.range".
- Arredondo (4/9) Mar 02 2018 Thank you. That's how I had it in my original code, I was just
Hi,
The following works as expected:
auto range = [1, 2, 3, 4, 5];
foreach (i, el; range) {
writeln(i, ": ", el);
}
but this slight modification doesn't:
auto range = iota(5);
foreach (i, el; range) {
writeln(i, ": ", el);
}
DMD 2.078.3 says:
Error: cannot infer argument types, expected 1 argument, not 2
The error message is not helpful either, because indicating the
types, as in:
foreach (int i, int el; range) { ... }
throws the same error.
What's going on here?
Arredondo
Mar 02 2018
On 02/03/2018 11:21 PM, Arredondo wrote:
Hi,
The following works as expected:
auto range = [1, 2, 3, 4, 5];
foreach (i, el; range) {
writeln(i, ": ", el);
}
s/range/array/
Arrays have a different foreach syntax than ranges do.
Mar 02 2018
On Friday, 2 March 2018 at 10:21:39 UTC, Arredondo wrote:Hi, The following works as expected: auto range = [1, 2, 3, 4, 5]; foreach (i, el; range) { writeln(i, ": ", el); } but this slight modification doesn't: auto range = iota(5); foreach (i, el; range) { writeln(i, ": ", el); } DMD 2.078.3 says: Error: cannot infer argument types, expected 1 argument, not 2 The error message is not helpful either, because indicating the types, as in: foreach (int i, int el; range) { ... } throws the same error. What's going on here? Arredondotry https://dlang.org/phobos/std_range.html#enumerateforeach (i, el; enumerate(range)) { writeln(i, ": ", el); }
Mar 02 2018
On Friday, 2 March 2018 at 10:27:27 UTC, Nicholas Wilson wrote:try https://dlang.org/phobos/std_range.html#enumerateThis worked. Thank you!
Mar 02 2018
On Friday, March 02, 2018 10:21:39 Arredondo via Digitalmars-d-learn wrote:
Hi,
The following works as expected:
auto range = [1, 2, 3, 4, 5];
foreach (i, el; range) {
writeln(i, ": ", el);
}
but this slight modification doesn't:
auto range = iota(5);
foreach (i, el; range) {
writeln(i, ": ", el);
}
DMD 2.078.3 says:
Error: cannot infer argument types, expected 1 argument, not 2
The error message is not helpful either, because indicating the
types, as in:
foreach (int i, int el; range) { ... }
throws the same error.
What's going on here?
foreach does not support indices for ranges, only arrays. When you have
foreach(e; range)
it gets lowered to
foreach(auto __range = range; !__range.empty; __range.popFront())
{
auto e = __range.front;
}
There are no indices involved there, and if a range isn't a random-access
range, it doesn't support any kind of indices anyway. The compiler would
have to add a variable to count the elements, and it doesn't support that.
Your best options are either lockstep with iota or enumerate:
https://dlang.org/phobos/std_range.html#lockstep
https://dlang.org/phobos/std_range.html#enumerate
- Jonathan M Davis
Mar 02 2018
On Friday, 2 March 2018 at 10:32:08 UTC, Jonathan M Davis wrote:
foreach does not support indices for ranges, only arrays. When
you have
foreach(e; range)
it gets lowered to
foreach(auto __range = range; !__range.empty;
__range.popFront())
{
auto e = __range.front;
}
There are no indices involved there, and if a range isn't a
random-access range, it doesn't support any kind of indices
anyway. The compiler would have to add a variable to count the
elements, and it doesn't support that.
I understand. I guess I was expecting the compiler to
automatically do something along the lines of what enumerate
does. Although, a nicer error message would have saved the day
just as well.
Arredondo
Mar 02 2018
On Friday, 2 March 2018 at 10:21:39 UTC, Arredondo wrote:
Hi,
The following works as expected:
auto range = [1, 2, 3, 4, 5];
foreach (i, el; range) {
writeln(i, ": ", el);
}
but this slight modification doesn't:
auto range = iota(5);
foreach (i, el; range) {
writeln(i, ": ", el);
}
DMD 2.078.3 says:
Error: cannot infer argument types, expected 1 argument, not 2
The error message is not helpful either, because indicating the
types, as in:
foreach (int i, int el; range) { ... }
throws the same error.
What's going on here?
Arredondo
What you want to do is call "enumerate" from "std.range".
auto range = iota(5).enumerate;
foreach (i, el; range) {
writeln(i, ": ", el);
}
You can also call "array" from "std.array".
auto range = iota(5).array;
foreach (i, el; range) {
writeln(i, ": ", el);
}
Mar 02 2018
On Friday, 2 March 2018 at 10:34:31 UTC, bauss wrote:
You can also call "array" from "std.array".
auto range = iota(5).array;
foreach (i, el; range) {
writeln(i, ": ", el);
}
Thank you. That's how I had it in my original code, I was just
trying to avoid gratuitous memory allocation.
Arredondo
Mar 02 2018









rikki cattermole <rikki cattermole.co.nz> 