digitalmars.D - how to do member function pointer in D?
- newbie (15/15) Jul 30 2008 Hi,
- Russell Lewis (10/32) Jul 30 2008 Although people have presented hacks to do this, there isn't a standard
- newbie (14/46) Jul 30 2008 The main problem is that I want to let the D compiler check the type for...
- BCS (10/66) Jul 30 2008 That is not something the type system can do. The two methods operate on...
- newbie (23/26) Jul 30 2008 I want my code to manipulate at function ptr level (instead of just call...
- BCS (11/40) Jul 30 2008 to clear that error:
- newbie (13/22) Jul 30 2008 Thanks.
- BCS (13/48) Jul 30 2008 same solution as befor (the issue is that the only thing you can put aft...
- newbie (13/25) Jul 30 2008 Why a function literal is not a constant expression?
- BCS (15/53) Jul 30 2008 but neither of those will be usefull unless you can assign more than one...
- u (3/10) Jul 30 2008 Can fnp be invoked on an actual object? and what's the syntax?
- BCS (2/15) Jul 31 2008
- JAnderson (5/41) Jul 30 2008 I'm not sure I completely understand either but I'll take a stab. What
- u (10/13) Jul 30 2008 Go back to my original question:
- Kirk McDonald (8/28) Jul 30 2008 There is a current thread in digitalmars.D.learn titled "Pointer to
- u (4/22) Jul 31 2008 I had hoped that D will offer better solution than C++'s member function...
- JAnderson (18/37) Jul 31 2008 //What about something like:
Hi, I want to be able to create a member function pointer type from a class (not from an object of that class), i.e. class A { void f() {} void g() {} } (member function pointer) mfp = &A.f; // what's the sytax for the type? // also I want the compiler to report error if I pass g() to mfp: mfp = &A.g; // type error! // and mfp can be invoked on different object instance of A: A a1, a2; mfp(a1); // call a1.f(), what's the right syntax? mfp(a2); // call a2.f() Thanks.
Jul 30 2008
Although people have presented hacks to do this, there isn't a standard way to do this in D. Of course, you could use a function literal to accomplish this: mfp = function void(A obj) { obj.f(); }; That isn't techically a member function pointer, but it is pretty similar. Do you have a compelling use case where you need member-function-pointer but delegates or the function literal above wouldn't work? I haven't yet heard of one, but of course they might exist. :) Russ newbie wrote:Hi, I want to be able to create a member function pointer type from a class (not from an object of that class), i.e. class A { void f() {} void g() {} } (member function pointer) mfp = &A.f; // what's the sytax for the type? // also I want the compiler to report error if I pass g() to mfp: mfp = &A.g; // type error! // and mfp can be invoked on different object instance of A: A a1, a2; mfp(a1); // call a1.f(), what's the right syntax? mfp(a2); // call a2.f() Thanks.
Jul 30 2008
The main problem is that I want to let the D compiler check the type for me: e.g. mfp1 = function void(A obj) { obj.f(); }; mfp2 = function void(A obj) { obj.g(); }; void function(A) fp; // suppose fp is what I intended to call A.f() fp = mfp1; // cass 1: OK fp = mfp2; // cass 2: OK mfp1 = mfp2; // cass 3: also OK Of course this is because fp is specified by the signature of it's arguments type and return type. I want a member function pointer type that is more strict than this, i.e. both case (2 & 3) will cause compiler type error. Another minor issue with your suggested approach is that: I have to write those wrappers for all the member function that I want to use. == Quote from Russell Lewis (webmaster villagersonline.com)'s articleAlthough people have presented hacks to do this, there isn't a standard way to do this in D. Of course, you could use a function literal to accomplish this: mfp = function void(A obj) { obj.f(); }; That isn't techically a member function pointer, but it is pretty similar. Do you have a compelling use case where you need member-function-pointer but delegates or the function literal above wouldn't work? I haven't yet heard of one, but of course they might exist. :) Russ newbie wrote:Hi, I want to be able to create a member function pointer type from a class (not from an object of that class), i.e. class A { void f() {} void g() {} } (member function pointer) mfp = &A.f; // what's the sytax for the type? // also I want the compiler to report error if I pass g() to mfp: mfp = &A.g; // type error! // and mfp can be invoked on different object instance of A: A a1, a2; mfp(a1); // call a1.f(), what's the right syntax? mfp(a2); // call a2.f() Thanks.
Jul 30 2008
Reply to Newbie,The main problem is that I want to let the D compiler check the type for me: e.g. mfp1 = function void(A obj) { obj.f(); }; mfp2 = function void(A obj) { obj.g(); }; void function(A) fp; // suppose fp is what I intended to call A.f() fp = mfp1; // cass 1: OK fp = mfp2; // cass 2: OK mfp1 = mfp2; // cass 3: also OK Of course this is because fp is specified by the signature of it's arguments type and return type. I want a member function pointer type that is more strict than this, i.e. both case (2 & 3) will cause compiler type error.That is not something the type system can do. The two methods operate on the same object type, take the same args and return the same type. As far as the type system system is concerned, they are identical. Maybe I'm missing something because what you seem to want doesn't seem useful to me, the restriction you seem to want would restrict the allowable values for fp to exactly one. If this is so, why do you want a variable? The only use I can think of is if you want to call a the f method from a base class on an object of a derived class. If this is the case you are subverting the type system so you are on your own.Another minor issue with your suggested approach is that: I have to write those wrappers for all the member function that I want to use. == Quote from Russell Lewis (webmaster villagersonline.com)'s articleAlthough people have presented hacks to do this, there isn't a standard way to do this in D. Of course, you could use a function literal to accomplish this: mfp = function void(A obj) { obj.f(); }; That isn't techically a member function pointer, but it is pretty similar. Do you have a compelling use case where you need member-function-pointer but delegates or the function literal above wouldn't work? I haven't yet heard of one, but of course they might exist. :) Russ newbie wrote:Hi, I want to be able to create a member function pointer type from a class (not from an object of that class), i.e. class A { void f() {} void g() {} } (member function pointer) mfp = &A.f; // what's the sytax for the type? // also I want the compiler to report error if I pass g() to mfp: mfp = &A.g; // type error! // and mfp can be invoked on different object instance of A: A a1, a2; mfp(a1); // call a1.f(), what's the right syntax? mfp(a2); // call a2.f() Thanks.
Jul 30 2008
Maybe I'm missing something because what you seem to want doesn't seem useful to me, the restriction you seem to want would restrict the allowable values for fp to exactly one. If this is so, why do you want a variable?I want my code to manipulate at function ptr level (instead of just calling the function). For now maybe what I can do is declare an invariant variable, which after initialization cannot be assigned to again. But I have trouble to get this code compiled: class A { void f() {writefln("f()");} void g() {writefln("g()");} } alias void function(A) FP; class B { static invariant FP mfp1 = function void(A obj) {obj.f();}; // line 11 } $ dmd memberfunptr.d memberfunptr.d(11): Error: cannot implicitly convert expression (__funcliteral1) of type void function(A) to invariant(void function(A)) Why I need to explicitly cast it? and even after I change the line to: static invariant FP mfp1 = cast(invariant FP)(function void(A obj) {obj.f();}); It says: $ dmd memberfunptr.d memberfunptr.d(11): Error: non-constant expression __funcliteral1 Anyone know what's the right way to write this? Thanks.
Jul 30 2008
Reply to Newbie,[...]Maybe I'm missing something because what you seem to want doesn't seem useful to me, the restriction you seem to want would restrict the allowable values for fp to exactly one. If this is so, why do you want a variable?I want my code to manipulate at function ptr level (instead of just calling the function). For now maybe what I can do is declare an invariant variable, which after initialization cannot be assigned to again. But I have trouble to get this code compiled: class A { void f() {writefln("f()");} void g() {writefln("g()");} } alias void function(A) FP; class B { static invariant FP mfp1 = function void(A obj) {obj.f();};// line 11 }static invariant FP mfp1 = cast(invariant FP)(function void(A obj) {obj.f();}); It says: $ dmd memberfunptr.d memberfunptr.d(11): Error: non-constant expression __funcliteral1to clear that error: static invariant FP mfp1; static this() { mfp1 = cast(invariant FP)(function void(A obj){obj.f();}); } OTOH I still have no clue what you are trying to do. I suspect their is a simperer way to do what you want. That said, /I/ often /enjoy/ doing things the far from simple way. <g>
Jul 30 2008
to clear that error: static invariant FP mfp1; static this() { mfp1 = cast(invariant FP)(function void(A obj){obj.f();}); }Thanks. Two more questions: 1) why the cast is necessary? shall I report a bug? e.g. invariant int a = 1; // I don't need the cast here! 2) how to do it as global variables? e.g. If I pull out it from B, and define as global variable: invariant FP mfp2 = cast(invariant FP)(function void(A obj) {obj.f();}); $ dmd memberfunptr.d memberfunptr.d(10): Error: non-constant expression __funcliteral1OTOH I still have no clue what you are trying to do. I suspect their is a simperer way to do what you want. That said, /I/ often /enjoy/ doing things the far from simple way. <g>I need to hold a collection of member-function pointers, and manipulate it in some way, then later make function calls on different object via these pointers. I want to protect myself that any these pointers shouldn't be re-assigned to other member functions with the same signatures.
Jul 30 2008
Reply to Newbie,same solution as befor (the issue is that the only thing you can put after the '=' ouside of a function is a constant expression and a function litteral isn't one) //at global scope (OTOH static's are globals) static invariant FP mfp1; static this() { mfp1 = cast(invariant FP)(function void(A obj){obj.f();}); }to clear that error: static invariant FP mfp1; static this() { mfp1 = cast(invariant FP)(function void(A obj){obj.f();}); }Thanks. Two more questions: 1) why the cast is necessary? shall I report a bug? e.g. invariant int a = 1; // I don't need the cast here! 2) how to do it as global variables? e.g. If I pull out it from B, and define as global variable: invariant FP mfp2 = cast(invariant FP)(function void(A obj) {obj.f();}); $ dmd memberfunptr.d memberfunptr.d(10): Error: non-constant expression __funcliteral1I still don't get it, what type of manipulation (outside self modifying code) can you do that doesn't allow switching in a different function with the same signature?OTOH I still have no clue what you are trying to do. I suspect their is a simperer way to do what you want. That said, /I/ often /enjoy/ doing things the far from simple way. <g>I need to hold a collection of member-function pointers, and manipulate it in some way, then later make function calls on different object via these pointers. I want to protect myself that any these pointers shouldn't be re-assigned to other member functions with the same signatures.
Jul 30 2008
same solution as befor (the issue is that the only thing you can put after the '=' ouside of a function is a constant expression and a function litteral isn't one)Why a function literal is not a constant expression? Especially after I defining a global top level wrapper function in this case. Under the hood, it should just be a raw pointer to some memory address, why this cannot be a constant?//at global scope (OTOH static's are globals) static invariant FP mfp1; static this() { mfp1 = cast(invariant FP)(function void(A obj){obj.f();}); }Thanks again. I can live with this workaround right now, but I'd really like to write it as simple as: invariant FP mfp2 = function void(A obj) {obj.f();}; // without the castI still don't get it, what type of manipulation (outside self modifying code)E.g. save in a hash-table, or use them as keys ... And I'd really like to do self modifying code ;-) I read somewhere that D plan have to AST macros? so we are closer to lisp: http://en.wikipedia.org/wiki/Greenspun%27s_Tenth_Rulecan you do that doesn't allow switching in a different function with the same signature?Yes, I do it manually (by writing program carefully). I want the help from the type system (or the language compiler) to protect me from such violation.
Jul 30 2008
Reply to Newbie,don't ask me.same solution as befor (the issue is that the only thing you can put after the '=' ouside of a function is a constant expression and a function litteral isn't one)Why a function literal is not a constant expression? Especially after I defining a global top level wrapper function in this case. Under the hood, it should just be a raw pointer to some memory address, why this cannot be a constant?but neither of those will be usefull unless you can assign more than one value to the type what I'm reading (and I must be missing somthing) is somthing like a hash table where the keys are the number 5 to the values are the number 3. One idea on what I'm missing; Do you want nothing at all to be assigname to the variable after the fist assigment? class Bob {void a(){} void b(){} } The_Type fnp = Bob.a; fnp = Bob.a; // valid or not? Do you care if other instances of the same type have pointers to other function? The_Type fnp = Bob.a;//at global scope (OTOH static's are globals) static invariant FP mfp1; static this() { mfp1 = cast(invariant FP)(function void(A obj){obj.f();}); }Thanks again. I can live with this workaround right now, but I'd really like to write it as simple as: invariant FP mfp2 = function void(A obj) {obj.f();}; // without the castI still don't get it, what type of manipulation (outside self modifying code)E.g. save in a hash-table, or use them as keys ...And I'd really like to do self modifying code ;-) I read somewhere that D plan have to AST macros? so we are closer to lisp: http://en.wikipedia.org/wiki/Greenspun%27s_Tenth_RuleIIRC that is with regards to program internals, not the external interfacecan you do that doesn't allow switching in a different function with the same signature?Yes, I do it manually (by writing program carefully). I want the help from the type system (or the language compiler) to protect me from such violation.
Jul 30 2008
Do you want nothing at all to be assigname to the variable after the fist assigment? class Bob {void a(){} void b(){} } The_Type fnp = Bob.a; fnp = Bob.a; // valid or not?Can fnp be invoked on an actual object? and what's the syntax? Bob bob = new Bob(); fnp(bob); // ? how to make this call?Do you care if other instances of the same type have pointers to other function? The_Type fnp = Bob.a;
Jul 30 2008
Reply to u,the whole thing is hypothetical so ...Do you want nothing at all to be assigname to the variable after the fist assigment? class Bob {void a(){} void b(){} } The_Type fnp = Bob.a; fnp = Bob.a; // valid or not?Can fnp be invoked on an actual object? and what's the syntax?Bob bob = new Bob(); fnp(bob); // ? how to make this call?Do you care if other instances of the same type have pointers to other function? The_Type fnp = Bob.a;
Jul 31 2008
newbie wrote:I'm not sure I completely understand either but I'll take a stab. What about using polymorphism? Where delegates can be any type of object interfaces restrict what sort of objects can be used with your hash-table. -Joelsame solution as befor (the issue is that the only thing you can put after the '=' ouside of a function is a constant expression and a function litteral isn't one)Why a function literal is not a constant expression? Especially after I defining a global top level wrapper function in this case. Under the hood, it should just be a raw pointer to some memory address, why this cannot be a constant?//at global scope (OTOH static's are globals) static invariant FP mfp1; static this() { mfp1 = cast(invariant FP)(function void(A obj){obj.f();}); }Thanks again. I can live with this workaround right now, but I'd really like to write it as simple as: invariant FP mfp2 = function void(A obj) {obj.f();}; // without the castI still don't get it, what type of manipulation (outside self modifying code)E.g. save in a hash-table, or use them as keys ... And I'd really like to do self modifying code ;-) I read somewhere that D plan have to AST macros? so we are closer to lisp: http://en.wikipedia.org/wiki/Greenspun%27s_Tenth_Rulecan you do that doesn't allow switching in a different function with the same signature?Yes, I do it manually (by writing program carefully). I want the help from the type system (or the language compiler) to protect me from such violation.
Jul 30 2008
I'm not sure I completely understand either but I'll take a stab. What about using polymorphism? Where delegates can be any type of object interfaces restrict what sort of objects can be used with your hash-table.Go back to my original question: How to create a variable which hold a particular function pointer of a class, and can be invoked on different objects of that class: fp = &(A.f); A a1, a2; a1.fp(); // how to make this invocation work? a2.fp(); And I have one more requirement that even if A.f() and A.g() have same signature, fp = &(A.g); // expect compiler report error here. How to declare the type of such fp?
Jul 30 2008
u wrote:There is a current thread in digitalmars.D.learn titled "Pointer to member variable again." It has turned into a discussion of this very topic. -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.orgI'm not sure I completely understand either but I'll take a stab. What about using polymorphism? Where delegates can be any type of object interfaces restrict what sort of objects can be used with your hash-table.Go back to my original question: How to create a variable which hold a particular function pointer of a class, and can be invoked on different objects of that class: fp = &(A.f); A a1, a2; a1.fp(); // how to make this invocation work? a2.fp(); And I have one more requirement that even if A.f() and A.g() have same signature, fp = &(A.g); // expect compiler report error here. How to declare the type of such fp?
Jul 30 2008
== Quote from Kirk McDonald (kirklin.mcdonald gmail.com)'s articleu wrote:I had hoped that D will offer better solution than C++'s member function pointer. Looks like currently it's more difficulty to do what I want in D. Probably I will live with the wrapper function for now.Go back to my original question: How to create a variable which hold a particular function pointer of a class, and can be invoked on different objects of that class: fp = &(A.f); A a1, a2; a1.fp(); // how to make this invocation work? a2.fp(); And I have one more requirement that even if A.f() and A.g() have same signature, fp = &(A.g); // expect compiler report error here. How to declare the type of such fp?There is a current thread in digitalmars.D.learn titled "Pointer to member variable again." It has turned into a discussion of this very topic.
Jul 31 2008
u wrote://What about something like: void funcBind(Obj, alias Func)(Obj obj) { obj.Func(); } ... alias funcBind!(A, f) fp; A a1, a2; fp(a1); fp(a2); alias funcBind!(A, g) fp; //Compiler error -> Duplicate //Note with a little more work you could make A implicit //and therefore have any class Type as the first parameter. I can't really see why function/member pointers are necessary for this situation since Member pointers are one to many and you seem to want a one-to-one relationship. -JoelI'm not sure I completely understand either but I'll take a stab. What about using polymorphism? Where delegates can be any type of object interfaces restrict what sort of objects can be used with your hash-table.Go back to my original question: How to create a variable which hold a particular function pointer of a class, and can be invoked on different objects of that class: fp = &(A.f); A a1, a2; a1.fp(); // how to make this invocation work? a2.fp(); And I have one more requirement that even if A.f() and A.g() have same signature, fp = &(A.g); // expect compiler report error here. How to declare the type of such fp?
Jul 31 2008