www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - pointer to member without 'this' - mem_fun like

reply Vlad <b100dian gmail.com> writes:
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
Mar 18 2008
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
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.
Mar 18 2008
parent reply Vlad <b100dian gmail.com> writes:
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
Mar 18 2008
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
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.
Mar 18 2008
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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.
Mar 18 2008
parent reply Vlad <b100dian gmail.com> writes:
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; }
Mar 18 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"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);
Mar 18 2008
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
-----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 Melbourne, Australia skype: derek.j.parnell -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) - WinPT 1.2.0 iD8DBQFH37LxB2Z2alRbg5gRAnHiAJ46iamP5hBGavj/I047vTSgVXB19ACg/JFD PpQJ2faWs584qzSTmu9ftvM= =HviD -----END PGP SIGNATURE-----
Mar 18 2008
parent reply Vlad <b100dian gmail.com> writes:
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)
Mar 18 2008
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
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'.
Mar 18 2008