On Fri, 01 Jun 2012 09:25:57 -0400, d coder <[email protected]> wrote:
Hello Steve, thanks for looking at this.
I see the code works when I create the delegate first and then send it to
template. That is the way you do it here.
void main() {
Foo f = new Foo();
auto dg = &f.foo; // need to make a symbol so it can be aliased
callfoo!(dg)();
}
But it does not work when I put &f.foo directly as the template argument.
That is correct. An alias cannot accept an *expression*, it can only
accept a *symbol*.
But it works when I say:
void main() {
Foo f = new Foo();
callfoo!(() {f.foo();})(f);
}
This is because a delegate literal (lambda) is an implicit symbol and an
expression at the same time. I think it's actually a special case for
alias.
Note that this is not as efficient, because you have a delegate that then
calls a member function, whereas the version I gave calls the member
function directly
But that still does not solve my problem. In my real code, I want to send
the delegate to a template class. And I am supposed to do that as a
member
of another class. So the code looks something like:
Class Bar(alias F) {
// Call F in some function here
}
Class Foo {
void foo();
Bar!(() {foo();}) bar;
}
Again this does not work. Maybe I am expecting too much from D. :-) I am
somewhat aware of the issues involved here. I have seen some earlier D
threads.
lambdas cannot exist outside a function scope. This is a limitation of D
that has been pointed out before, and I think it should be made available,
but don't hold your breath :) D is just starting to get more filled out
in the area of lambdas.
But then I thought there might be a way to pass the method function
literal
(foo) and separately the this pointer of Foo object and then combine the
two at the other end (inside Bar).
There is a way, as I hinted :)
I'll show you how, but be prepared to deal with ugliness!
typeof(&F.init.foo) dg; // alternately: void delegate() dg;
dg.funcptr = &F.foo; // use the type, not the instance, to get the
function pointer itself instead of a delegate
dg.ptr = cast(void *)f; // set f is the context pointer
dg(); // now should call f.foo
Note that this is *not* a virtual call. That is currently impossible to
do without using a lambda.
-Steve