tags:

views:

64

answers:

1

I have:

Foo foo = new Foo();

foreach (i; 0..10)
{
  Bar bar = foo.getBar(i);
  ...
}

I want to be able to instead say (equivalently):

foreach (bar; foo.getAllBars())
{
  ...
}

How do I go about implementing getAllBars()?

I figured something like this:

class Foo
{
  auto getAllBars()
  {
    return map!(getBar)(iota(10));
  }
}

But you can't do that of course because getBar depends on the this parameter, which will go out of scope. The same applies if you try to create a local function or delegate. I also considered creating a function object with opCall, but you can't use those with map (can you?).

Some requirements:

  • The returned range must be lazy (so no copying it into an array first)
  • Assume that getBar is the only way to get at the data.
  • I want the map to be encapsulated by the class (i.e. no moving the map to the call site).
+1  A: 

std.algorithm.map works via a template alias parameter, and binding is at compile time. Walter Bright (the D language designer) hasn't been clear yet on the semantics of template alias parameters in these situations, though what you're trying to do seems to somehow work in practice. Clarifying this is a todo (I think). Perhaps you would be better off asking this on the digitalmars.d newsgroup, as this would get Walter's attention and encourage him to clarify the semantics.

dsimcha
Could you elaborate on what you mean be "what you're trying to do seems to somehow work in practice." -- it certainly doesn't work for me.
Peter Alexander
@Peter: I'm as confused as you about what works and what doesn't. All I'm saying is that in some cases delegates, etc. work in practice even though I have no idea how. This really needs to be clarified and needs to be a bug report. There is simply no good answer to it right now other than possibly in Walter's head.
dsimcha