Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 18, 2008 pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Hi list, I was wondering if D has something like C's mem_fun, where one can pass a pointer to a member function of a class, that later can be called with various 'this' instances. Furthermore, does a similar mechanism for data members exist? Thank you, Vlad |
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad | Vlad wrote: > Hi list, > > I was wondering if D has something like C's mem_fun, where one can pass a pointer to a member function of a class, that later can be called with various 'this' instances. No, sorry. It does have delegates, but then the vtable lookup is performed when the delegate is constructed. If that's okay, (i.e. if you only use this for instances of the same type or subtypes that don't override that method) you should be able to take a delegate and assign a new 'this' (.ptr) to it before calling it... > Furthermore, does a similar mechanism for data members exist? No. You could hack something together with pointer arithmetic, but it won't be pretty. Some kind of wrapper could perhaps be written as a struct template though. |
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frits van Bommel | Frits van Bommel wrote: > Vlad wrote: >> Hi list, >> >> I was wondering if D has something like C's mem_fun, where one can pass a pointer to a member function of a class, that later can be called with various 'this' instances. > > No, sorry. > It does have delegates, but then the vtable lookup is performed when the delegate is constructed. If that's okay, (i.e. if you only use this for instances of the same type or subtypes that don't override that method) you should be able to take a delegate and assign a new 'this' (.ptr) to it before calling it... > Thanks, this should do it - however I still need an(other) instance when passing the delegate, right? >> Furthermore, does a similar mechanism for data members exist? > > No. You could hack something together with pointer arithmetic, but it won't be pretty. Some kind of wrapper could perhaps be written as a struct template though. Yeah, that was silly of me:). I will be using 'setters' and revert to the previous answer. Thank you very much! Vlad |
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad | Vlad wrote:
> Frits van Bommel wrote:
>> Vlad wrote:
>>> Hi list,
>>>
>>> I was wondering if D has something like C's mem_fun, where one can pass a pointer to a member function of a class, that later can be called with various 'this' instances.
>>
>> No, sorry.
>> It does have delegates, but then the vtable lookup is performed when the delegate is constructed. If that's okay, (i.e. if you only use this for instances of the same type or subtypes that don't override that method) you should be able to take a delegate and assign a new 'this' (.ptr) to it before calling it...
>>
>
> Thanks, this should do it - however I still need an(other) instance when passing the delegate, right?
You *might* get away with using &Class.memberfn to fill in dg.funcptr. But I've never tried this, so you might want to make sure it works before using it for anything serious.
|
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad Attachments: | On Tue, 18 Mar 2008 11:27:23 +0200, Vlad wrote:
> Hi list,
>
> I was wondering if D has something like C's mem_fun, where one can pass a pointer to a member function of a class, that later can be called with various 'this' instances.
Excuse my ignorance, but what is the benefit of this technique?
- --
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
|
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frits van Bommel | "Frits van Bommel" <fvbommel@REMwOVExCAPSs.nl> wrote in message news:fro9ip$dib$1@digitalmars.com... >> >> Thanks, this should do it - however I still need an(other) instance when passing the delegate, right? > > You *might* get away with using &Class.memberfn to fill in dg.funcptr. But I've never tried this, so you might want to make sure it works before using it for anything serious. It does work, at least in my experience. Of course this bypasses any vtable lookup so you'll just be getting the implementation of the method from Class. |
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On Tue, 18 Mar 2008 11:27:23 +0200, Vlad wrote:
>
>> Hi list,
>>
>> I was wondering if D has something like C's mem_fun, where one can pass a pointer to a member function of a class, that later can be called with various 'this' instances.
>
> Excuse my ignorance, but what is the benefit of this technique?
>
> - --
> Derek Parnell
Example: writing a map()-like function that works on a collection of objects and calling a method on them, instead of a free function
Pseudocode:
(with a 'free function'):
string in[] = ...
int out[] = map (in, len);
(with a 'member_fun'):
T in[] = ...
T out[] = map(in, &T.do_something);
or even:
T in[] = ...
int out[] = map(in, &T.get_some_int_property)
|
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > "Frits van Bommel" <fvbommel@REMwOVExCAPSs.nl> wrote in message news:fro9ip$dib$1@digitalmars.com... >>> Thanks, this should do it - however I still need an(other) instance when passing the delegate, right? >> You *might* get away with using &Class.memberfn to fill in dg.funcptr. But I've never tried this, so you might want to make sure it works before using it for anything serious. > > It does work, at least in my experience. Of course this bypasses any vtable lookup so you'll just be getting the implementation of the method from Class. > > It didn't work for me (see full code below).. On the same topic, I see in the "Template parameters" heading here (http://www.digitalmars.com/d/1.0/templates-revisited.html) that template syntax to force a member of a type does not exist either:( I am trying to generalize the initialization of the fields of a struct/class with setters from something like a database rowset (and also to learn D;) (here's the code: change &author.name to &Author.name) import std.stdio; void set_field(T,F)(T instance, void delegate(F) setter) { setter("zz"); } class Author { private string _name; string name() { return _name; } void name(string name) { _name = name; } } int main(char[][] args) { Author author = new Author(); set_field!(Author,string)(author, &author.name); writefln(author.name); return 0; } |
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad | "Vlad" <b100dian@gmail.com> wrote in message news:47DFC12D.8020604@gmail.com... > Jarrett Billingsley wrote: >> "Frits van Bommel" <fvbommel@REMwOVExCAPSs.nl> wrote in message news:fro9ip$dib$1@digitalmars.com... >>>> Thanks, this should do it - however I still need an(other) instance when passing the delegate, right? >>> You *might* get away with using &Class.memberfn to fill in dg.funcptr. But I've never tried this, so you might want to make sure it works before using it for anything serious. >> >> It does work, at least in my experience. Of course this bypasses any vtable lookup so you'll just be getting the implementation of the method from Class. > > It didn't work for me (see full code below).. > (here's the code: change &author.name to &Author.name) > set_field!(Author,string)(author, &author.name); No, that isn't going to work, because when you get &Author.name, you only have one half of the puzzle. It's just a function. You need to factor in the instance somehow. void set_field(T,F)(T instance, void function(F) setter) { void delegate(F) dg; dg.funcptr = setter; dg.ptr = cast(void*)instance; dg("zz"); } This is one way to do it. Another way is to have the code generated at compile time instead: template set_field(char[] name) { void set_field(T)(T instance) { mixin("instance." ~ name ~ " = `zz`;"); } } ... set_field!("name")(author); |
March 18, 2008 Re: pointer to member without 'this' - mem_fun like | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vlad | Vlad wrote:
> Example: writing a map()-like function that works on a collection of objects and calling a method on them, instead of a free function
>
> Pseudocode:
> (with a 'free function'):
>
> string in[] = ...
> int out[] = map (in, len);
>
> (with a 'member_fun'):
> T in[] = ...
> T out[] = map(in, &T.do_something);
>
> or even:
> T in[] = ...
> int out[] = map(in, &T.get_some_int_property)
Normal D way to do something like this:
---
// Note: 'in' and 'out' are keywords so they can't be used as variables
T[] input = ...
// free function:
int[] out1 = map (input, &len); // if map accepts raw function pointers
// otherwise, use something like below
// member function:
U[] out2 = map(input, (T t) { return t.do_something; });
// or even:
int[] out3 = map(input, (T t) { op1(t); op2(t); return op3(t); });
---
It's a bit longer, but doesn't require extra getters & setters just for this.
The second parameter to map in the latter two examples is a delegate literal; it can contain any block of code, and can even access local variables in the surrounding code if needed.
You'll need to overload map (or turn it into a template function) if you want to also accept function pointers as in my first example. Of course if you want it to allow multiple input and output array types it'll have to be a template function anyway so that shouldn't be a problem.
P.S. Normally the operation to apply is the *first* parameter to a function called 'map'.
|
Copyright © 1999-2021 by the D Language Foundation