digitalmars.D.learn - Converting function pointers to delegates
- Ryan Voots (25/25) Apr 14 2014 I'm porting some code from D1 to D2 and this is the final error
- Adam D. Ruppe (9/11) Apr 14 2014 Try taking the address of this before casting it. So more like
- Andrej Mitrovic (6/13) Apr 14 2014 That's not true.
- Artur Skawina (8/23) Apr 15 2014 It *is* true. Classes are /reference types/, not references to classes.
- Andrej Mitrovic (2/3) Apr 15 2014 I meant the part where he said you can't cast a reference to a pointer. ...
- Artur Skawina (15/19) Apr 15 2014 He obviously meant that you can't get a pointer to the object, that the
- Adam D. Ruppe (7/10) Apr 15 2014 Yea, you can cast a class reference to void* (which does include
- Andrej Mitrovic (3/5) Apr 15 2014 Ah right. I don't do this often so I forgot. The proper code would be:
- Andrej Mitrovic (6/9) Apr 14 2014 You can replaced it with std.functional.toDelegate.
I'm porting some code from D1 to D2 and this is the final error i'm getting from DMD and GDC. I have no idea what is going on with it though. /** * Convert any function pointer to a delegate. * _ From: http://www.digitalmars.com/d/archives/digitalmars/D/easily_convert_any_method_function_to_a delegate_55827.html */ R delegate(P) toDelegate(R, P...)(R function(P) fp) { struct S { R Go(P p) // P is the function args. { return (cast(R function(P))(cast(void*)this))(p); } } return &(cast(S*)(cast(void*)fp)).Go; } DMD tells me: src/yage/core/misc.d(164): Error: e2ir: cannot cast this of type S to type void* The code itself you can see at: https://bitbucket.org/simcop2387/yage/src/0542cea5eefabf4c90b822cf26ec1062ed0fcb64/src/yage/core/misc.d?at=default#cl-161 and where it gets called: https://bitbucket.org/simcop2387/yage/src/0542cea5eefabf4c90b822cf26ec1062ed0fcb64/src/yage/core/repeater.d?at=default#cl-47 To be perfectly honest I'm not sure what it's doing to figure out how to fix it.
Apr 14 2014
On Monday, 14 April 2014 at 17:45:52 UTC, Ryan Voots wrote:src/yage/core/misc.d(164): Error: e2ir: cannot cast this of type S to type void*Try taking the address of this before casting it. So more like cast(void*)&this IIRC in D1 this was a pointer, whereas in D2 this is a reference. You can't cast a reference to pointer directly (at least not without overloading the cast operator) but you can take its address to fetch a pointer out of it and then work with that. BTW see also: http://dlang.org/phobos/std_functional.html#toDelegate
Apr 14 2014
On Monday, 14 April 2014 at 17:48:31 UTC, Adam D. Ruppe wrote:On Monday, 14 April 2014 at 17:45:52 UTC, Ryan Voots wrote:That's not true. And I think the issue in his diagnostic is that he used it with a struct. You can't cast 'this' of a struct to a pointer (you'd have to use &this), but you can cast a class reference to a pointer.src/yage/core/misc.d(164): Error: e2ir: cannot cast this of type S to type void*Try taking the address of this before casting it. So more like cast(void*)&this IIRC in D1 this was a pointer, whereas in D2 this is a reference. You can't cast a reference to pointer directly.
Apr 14 2014
On 04/14/14 19:51, Andrej Mitrovic wrote:On Monday, 14 April 2014 at 17:48:31 UTC, Adam D. Ruppe wrote:It *is* true. Classes are /reference types/, not references to classes. [There's no such thing as a "class payload" in D. Also, you can have a D-ref to a D-class.] D doesn't have "true" references, just a storage-class based hack, that only supports a small subset of ref functionality. But these pseudo-refs still act as the objects they point to. arturOn Monday, 14 April 2014 at 17:45:52 UTC, Ryan Voots wrote:That's not true. And I think the issue in his diagnostic is that he used it with a struct. You can't cast 'this' of a struct to a pointer (you'd have to use &this), but you can cast a class reference to a pointer.src/yage/core/misc.d(164): Error: e2ir: cannot cast this of type S to type void*Try taking the address of this before casting it. So more like cast(void*)&this IIRC in D1 this was a pointer, whereas in D2 this is a reference. You can't cast a reference to pointer directly.
Apr 15 2014
On 4/15/14, Artur Skawina <art.08.09 gmail.com> wrote:It *is* true. Classes are /reference types/, not references to classes.I meant the part where he said you can't cast a reference to a pointer. You can.
Apr 15 2014
On 04/15/14 13:30, Andrej Mitrovic wrote:On 4/15/14, Artur Skawina <art.08.09 gmail.com> wrote:He obviously meant that you can't get a pointer to the object, that the reference points to, just by casting and w/o address-of. int* f(ref int r) { return cast(int*)r; } void main() { int a = 42; import std.stdio; writeln(&a); writeln(f(a)); } Yes, this will compile, and, yes, you can "cast a reference to a pointer", but this does not mean that you will get a pointer to 'a'. The D situation wrt to refs and classes is bad enough; saying that you "can cast a reference to a pointer" will only confuse people. arturIt *is* true. Classes are /reference types/, not references to classes.I meant the part where he said you can't cast a reference to a pointer. You can.
Apr 15 2014
On Tuesday, 15 April 2014 at 12:05:09 UTC, Artur Skawina wrote:He obviously meant that you can't get a pointer to the object, that the> reference points to, just by casting and w/o address-of.Yea, you can cast a class reference to void* (which does include this inside a class), but not a ref storage class thingy which includes this inside a struct. Since the topic at hand was a struct I got a bit sloppy in my wording. So I'd say we're all partially right, just in different contexts :)
Apr 15 2014
On 4/15/14, Artur Skawina <art.08.09 gmail.com> wrote:He obviously meant that you can't get a pointer to the object, that the reference points to, just by casting and w/o address-of.Ah right. I don't do this often so I forgot. The proper code would be: int* f(ref int r) { return &r; }
Apr 15 2014
On Monday, 14 April 2014 at 17:45:52 UTC, Ryan Voots wrote:/** * Convert any function pointer to a delegate. * _ From: http://www.digitalmars.com/d/archives/digitalmarsYou can replaced it with std.functional.toDelegate. As for its use-case, if some API or function supports only delegates but you want to pass in a function, you would wrap the function with toDelegate and then pass the delegate to the API/function.
Apr 14 2014