On Mon, 28 Sep 2009 18:58:01 -0400, gzp <ga...@freemail.hu> wrote:

Hello,

Iám new to D so i might be all wrong. Given the code:

class Foo {
        int opApply( int delegate(ref real) dg ) {...} //A.
        int opApply( int delegate(real) dg ) {...} // B,
}

...
        Foo foo = new Foo;
        foreach( a; foo ) {...}  // 1.
        foreach( ref a; foo ) {...} // 2,

Is it normal that, the A. version (with ref) is called for both cases and if the A is eliminated, only the 2. foreach loop will compile ? The second case works as i expected but what about the first case - the B. function won't be called ever ?

This is an undocumented limitation of the foreach/opApply model. Here is what happens when you call foreach.

foreach(real x; foo)
{
  writeln(x);
}

The compiler creates a local function with some internal name, like FE1, then calls the opApply with that function. If you don't specify ref for the args, it factors out the ref. For example:

int FE1(ref real _x)
{
  auto x = _x; // auto generated code factors out reference
  // now the foreach body goes here
  writeln(x);

  // auto-generated return
  return 0;
}

// auto-generated call to opApply
foo.opApply(&FE1);

The factoring out of ref is to prevent you from having to write 2 delegate functions if you want to handle both cases, since the non-ref version is easy to implement in terms of the ref version. However, I think it is useful to be able to limit the code from allowing ref.

See my already-reported enhancement for this issue:

http://d.puremagic.com/issues/show_bug.cgi?id=2443


Furthermore, i wanted to create a const iterator

class Foo {
        int opApply( int delegate(ref real) dg ) {...} //A.
        const int opApply( int delegate(real) dg ) {...} // B,
}

...
        Foo foo = new Foo;
        const Foo f2 = foo;
        foreach( a; f2 ) {...}  // 1.
        foreach( ref a; foo ) {...} // 2,

It won't compile. (dmd 2.032) (I expected that, for the 1. loop the B version and for the 2. loop the A version of the functions'd be called)

So what is the D way to create const iterator ?

There is definitely some room for improvement on const opApply.

http://d.puremagic.com/issues/show_bug.cgi?id=2442

I also have one other opApply enhancment which I think would help make code much more readable:

http://d.puremagic.com/issues/show_bug.cgi?id=2498

Please vote for these issues so they are considered!

-Steve

Reply via email to