digitalmars.D.learn - Issue with typeof
- StarGrazer (13/13) Mar 20 2017 typeof(&method) fails unless method is static. Says & requires
- Moritz Maxeiner (26/34) Mar 20 2017 One warning beforehand:
- Moritz Maxeiner (34/37) Mar 20 2017 This may sound harder that it is, btw. A template that does
- StarGrazer (2/8) Mar 20 2017 Thanks.
- ag0aep6g (33/43) Mar 21 2017 Works for me:
- StarGrazer (6/25) Mar 21 2017 Yes, but you changed it. I didn't have C. Initially this wasn't a
- ag0aep6g (8/28) Mar 21 2017 I just filled the blanks you left. Note that my snippet still includes
typeof(&method) fails unless method is static. Says & requires this. But for typeof, it shouldn't matter and should pass. So how to get a function pointer to a non static member function(of an interface)? I've tried creating the type like T t; typeof(&t.method) fptr; but same issue. It may be because T is an interface, but again, it shouldn't matter. I just want the function pointer declaration. e.g., `void function();` for `void foo();` This is to avoid building the declaration myself which may be error prone.
Mar 20 2017
On Monday, 20 March 2017 at 16:55:38 UTC, StarGrazer wrote:typeof(&method) fails unless method is static. Says & requires this. But for typeof, it shouldn't matter and should pass. So how to get a function pointer to a non static member function(of an interface)?One warning beforehand: If the method is not static, a function pointer by itself is useless, you should use a delegate; non-static methods have a hidden this parameter (OOP), merely taking the address of such a method (i.e. a function pointer) would leave you with something you could not invoke, since you can't explicitly pass the hidden this to a function pointer.I've tried creating the type like T t; typeof(&t.method) fptr;The correct syntax for the above would be either typeof(&T.method) fptr; or typeof(t.method)* fptr; , both of which declare fptr as a function pointer. You won't be able to use fptr the way I think you expect, however: fptr = &t.method; will not work, because the RHS is a delegate (which uses the address of t as the hidden this parameter implicitly) and the LHS requires a function pointer. For most cases, this is exactly what auto storage class is for: auto fptr = &t.method; If you need the type for another function's parameter's type, then that won't work, of course. Two solutions I see there are 1) Make that function templatized 2) Create a template that can be used like this (you'll want to consult std.traits for this): void foo (delegateOf!(T.method) fptr) {}
Mar 20 2017
On Monday, 20 March 2017 at 17:58:32 UTC, Moritz Maxeiner wrote:2) Create a template that can be used like this (you'll want to consult std.traits for this): void foo (delegateOf!(T.method) fptr) {}This may sound harder that it is, btw. A template that does exactly that is the following (template constraints that verify `method` to actually be a member method left out): template DelegateTypeOf(alias method) { import std.array : replaceFirst; import std.string : format; enum fnType = typeof(&method).stringof; enum dgType = fnType.replaceFirst("function", "delegate"); mixin(`alias DelegateTypeOf = %s;`.format(dgType)); } Including the above, a full example would be the following: interface T { void method(int x); } void foo(DelegateTypeOf!(T.method) dg) { dg(42); } class X : T { void method(int x) { import std.stdio : writefln; } } void main() { T t = new X; foo(&t.method); }
Mar 20 2017
On Monday, 20 March 2017 at 18:27:39 UTC, Moritz Maxeiner wrote:On Monday, 20 March 2017 at 17:58:32 UTC, Moritz Maxeiner wrote:Thanks.[...]This may sound harder that it is, btw. A template that does exactly that is the following (template constraints that verify `method` to actually be a member method left out): [...]
Mar 20 2017
On 03/20/2017 05:55 PM, StarGrazer wrote:typeof(&method) fails unless method is static. Says & requires this.Works for me: ---- class C { void method() {} typeof(&method) x; } typeof(&C.method) y; ---- Tested with dmd 2.073.2. Note that the type of x and y is `void function()`, not `void delegate()`. That's quite awful. In my opinion, `&method` shouldn't work like this, but it does.But for typeof, it shouldn't matter and should pass.I disagree. `typeof(foo)` should only work when `foo` works. And `&method` shouldn't work when there's no `this`.So how to get a function pointer to a non static member function(of an interface)? I've tried creating the type like T t; typeof(&t.method) fptr; but same issue. It may be because T is an interface, but again, it shouldn't matter. I just want the function pointer declaration.Works with an interface, too: ---- interface T { void method(); } T t; typeof(&t.method) fptr1; typeof(&T.method) fptr2; ---- Here, fptr1 has type `void delegate()` which is ok, but fptr2 has type `void function()` which is pretty bad. So, what you tried compiles for me and should work. To keep it more hygienic, you can put the `T t;` and `typeof(&t.method)` in an immediately called function literal: ---- typeof(() { T t; return &t.method; } ()) fptr3; ----e.g., `void function();` for `void foo();`Really should be `void delegate()`. With the `function` type you're losing the `this` pointer.
Mar 21 2017
On Tuesday, 21 March 2017 at 15:01:43 UTC, ag0aep6g wrote:On 03/20/2017 05:55 PM, StarGrazer wrote:Yes, but you changed it. I didn't have C. Initially this wasn't a problem.typeof(&method) fails unless method is static. Says & requires this.Works for me: ---- class C { void method() {} typeof(&method) x; } typeof(&C.method) y; ---- Tested with dmd 2.073.2.---- typeof(() { T t; return &t.method; } ()) fptr3; ----You are making assumptions... my functions where static and I was trying to convert them to non-static methods and this is where the trouble started creeping in.e.g., `void function();` for `void foo();`Really should be `void delegate()`. With the `function` type you're losing the `this` pointer.
Mar 21 2017
On 03/21/2017 04:09 PM, StarGrazer wrote:On Tuesday, 21 March 2017 at 15:01:43 UTC, ag0aep6g wrote:I just filled the blanks you left. Note that my snippet still includes `typeof(&method)` verbatim. The added `typeof(&C.method)` is just bonus. If you have code that fails unexpectedly, please feel free to post it. [...]On 03/20/2017 05:55 PM, StarGrazer wrote:Yes, but you changed it. I didn't have C. Initially this wasn't a problem.typeof(&method) fails unless method is static. Says & requires this.Works for me: ---- class C { void method() {} typeof(&method) x; } typeof(&C.method) y; ---- Tested with dmd 2.073.2.You are making assumptions... my functions where static and I was trying to convert them to non-static methods and this is where the trouble started creeping in.Going from static to non-static means going from `function` to `delegate`. I don't think there's a way around that. You can get a `function` type from a method, but it won't be useful with actual methods.
Mar 21 2017