Thread overview
"Cannot infer argument types" for foreach over byLine
Jan 24, 2015
Meta
Jan 24, 2015
Ali Çehreli
Jan 24, 2015
Meta
January 24, 2015
import std.stdio;

void main()
{
    foreach (i, line; file.byLine())
    {
        writeln(line);
    }
}

This code gives me the error:

Error: cannot infer argument types, expected 1 argument, not 2

This is a very obtuse compiler message considering how simple the code is; I know it's got something to do with the foreach statement and what byLine() returns, but I can't seem to get it to compile without removing `i`.
January 24, 2015
On 01/24/2015 12:14 AM, Meta wrote:

> import std.stdio;
>
> void main()
> {
>      foreach (i, line; file.byLine())

Unless the range itself provides explicitly, automatic counter is available only for arrays. Otherwise, you have to enumerate yourself. ;)

import std.stdio;
import std.range;

void main()
{
    foreach (i, element; iota(42, 45).enumerate) {
        writefln("%s: %s", i, element);
    }
}

I am not sure whether std.range.enumerate is available in the current compiler. If not, you can use zip and sequence:

    foreach (i, element; zip(sequence!"n", iota(42, 45))) {
        writefln("%s: %s", i, element);
    }

However, that code is taking advantage of automatic tuple expansion, which causes trouble in some cases but not here. If you don't want that, you can expand the tuple explicitly:

    foreach (t; zip(sequence!"n", iota(42, 45))) {
        writefln("%s: %s", t[0], t[1]);
    }

>      {
>          writeln(line);
>      }
> }
>
> This code gives me the error:
>
> Error: cannot infer argument types, expected 1 argument, not 2
>
> This is a very obtuse compiler message considering how simple the code
> is; I know it's got something to do with the foreach statement and what
> byLine() returns, but I can't seem to get it to compile without removing
> `i`.

Ali

January 24, 2015
On Saturday, 24 January 2015 at 08:44:45 UTC, Ali Çehreli wrote:
> On 01/24/2015 12:14 AM, Meta wrote:
>
> > import std.stdio;
> >
> > void main()
> > {
> >      foreach (i, line; file.byLine())
>
> Unless the range itself provides explicitly, automatic counter is available only for arrays. Otherwise, you have to enumerate yourself. ;)

Hmm, how have I not known that until now? I thought that feature worked for all ranges. Thanks.
January 26, 2015
On 1/24/15 11:15 AM, Meta wrote:
> On Saturday, 24 January 2015 at 08:44:45 UTC, Ali Çehreli wrote:
>> On 01/24/2015 12:14 AM, Meta wrote:
>>
>> > import std.stdio;
>> >
>> > void main()
>> > {
>> >      foreach (i, line; file.byLine())
>>
>> Unless the range itself provides explicitly, automatic counter is
>> available only for arrays. Otherwise, you have to enumerate yourself. ;)
>
> Hmm, how have I not known that until now? I thought that feature worked
> for all ranges. Thanks.

It would be confusing. Imagine this scenario:

auto l = file.byLine();
l.popFront();

foreach(i, line; l)

Now, the line numbers are off by one, because the ByLine struct does not track them.

-Steve