Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
March 02, 2018 Unexpected behaviour of foreach statement | ||||
---|---|---|---|---|
| ||||
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 |
March 02, 2018 Re: Unexpected behaviour of foreach statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arredondo | 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.
|
March 02, 2018 Re: Unexpected behaviour of foreach statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arredondo | 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 try https://dlang.org/phobos/std_range.html#enumerate > foreach (i, el; enumerate(range)) { > writeln(i, ": ", el); > } |
March 02, 2018 Re: Unexpected behaviour of foreach statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On Friday, 2 March 2018 at 10:27:27 UTC, Nicholas Wilson wrote:
> try
> https://dlang.org/phobos/std_range.html#enumerate
This worked. Thank you!
|
March 02, 2018 Re: Unexpected behaviour of foreach statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arredondo | 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 |
March 02, 2018 Re: Unexpected behaviour of foreach statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arredondo | 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);
}
|
March 02, 2018 Re: Unexpected behaviour of foreach statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | 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
|
March 02, 2018 Re: Unexpected behaviour of foreach statement | ||||
---|---|---|---|---|
| ||||
Posted in reply to bauss | 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
|
Copyright © 1999-2021 by the D Language Foundation