| Thread overview | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Attachments:
| Hello All Particularly I would like to know if it is possible at all in D to invoke a class method transferred to a scope outside the class as an alias argument. Regards - Puneet | |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to d coder | On Friday, 1 June 2012 at 12:32:55 UTC, d coder wrote:
> Hello All
>
> Particularly I would like to know if it is possible at all in D to invoke a
> class method transferred to a scope outside the class as an alias argument.
>
> Regards
> - Puneet
I think it should work, if I understand correctly what you want to do.
--
/Jacob Carlborg
| |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to d coder | On Fri, 01 Jun 2012 08:32:02 -0400, d coder <dlang.coder@gmail.com> wrote:
> Hello All
>
> Particularly I would like to know if it is possible at all in D to invoke a
> class method transferred to a scope outside the class as an alias argument.
Is it possible? Yes. But not easy. I won't go into the details, but suffice to say, you must reconstruct a delegate and then call it.
D does not have "pointers to members" like C++ does. So when you alias f.foo you are actually aliasing the function F.foo (without the context pointer, and without a parameter to be able to place it).
However, there is another way -- use delegates:
void main() {
Foo f = new Foo();
auto dg = &f.foo; // need to make a symbol so it can be aliased
callfoo!(dg)();
}
Sorry if this is disappointing, D is not as low-level in this area. But if you are willing to always pair a member function with its context pointer, delegates are much simpler and more useful than pointers to members:
void main() {
Foo f = new Foo;
auto dg = &f.foo;
dg();
}
-Steve
| |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| 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. But it works when I say:
void main() {
Foo f = new Foo();
callfoo!(() {f.foo();})(f);
}
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.
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).
Regards
- Puneet
| |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to d coder | On 2012-06-01 15:25, d coder 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. But it works when I say: > > void main() { > Foo f = new Foo(); > callfoo!(() {f.foo();})(f); > } > > 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. > > 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). > > Regards > - Puneet > Originally you said "class method", so I was thinking like this: class Foo { static void bar () { writeln("bar"); } } void foo (alias m) () { m(); } void main () { foo!(Foo.bar); } But if you actually mean "instance method" you need to use delegates and possible compose them as Steven showed. -- /Jacob Carlborg | |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to d coder | On Fri, 01 Jun 2012 09:25:57 -0400, d coder <dlang.coder@gmail.com> 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 | |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Another way to phrase it would be that D is forcing you to to use templates where they really aren't meant to be used. :\ | |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| Hello Steve > There is a way, as I hinted :) > > I'll show you how, but be prepared to deal with ugliness! > All this smart code would be hidden from the end-users so I really do not care. > 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 > > Let me understand this. Is F here an alias for foo? If so why I need to mention stuff like &F.foo? It would defeat my purpose if I have to mention foo by name. But the code you have put here does give me hope. Just that I am not able to grasp what F and foo represent here. Probably you mean F is the type of the class that instantiates the template and foo is the alias for the method I want to call. Am I right? > Note that this is *not* a virtual call. That is currently impossible to do without using a lambda. > For my purpose that is perfectly fine for now. Thanks for throwing light on delegates. You have shown me hope :) - Regards - Puneet | |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2012-06-01 15:51, Steven Schveighoffer wrote: > On Fri, 01 Jun 2012 09:25:57 -0400, d coder <dlang.coder@gmail.com> wrote: >> 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. That can't work since there is no this-reference for "foo"? -- /Jacob Carlborg | |||
June 01, 2012 Re: Calling an alias for a Class method in another scope | ||||
|---|---|---|---|---|
| ||||
Posted in reply to d coder | On Fri, 01 Jun 2012 10:09:49 -0400, d coder <dlang.coder@gmail.com> wrote:
> Hello Steve
>
>
>> There is a way, as I hinted :)
>>
>> I'll show you how, but be prepared to deal with ugliness!
>>
>
> All this smart code would be hidden from the end-users so I really do not
> care.
>
>
>> 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
>>
>> Let me understand this. Is F here an alias for foo? If so why I need to
> mention stuff like &F.foo?
Sorry! I meant Foo, not F. F should be replaced with whatever the class type is.
-Steve
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply