www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Issue with typeof

reply StarGrazer <Stary Night.com> writes:
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
next sibling parent reply Moritz Maxeiner <moritz ucworks.org> writes:
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
parent reply Moritz Maxeiner <moritz ucworks.org> writes:
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; writefln("Hello, world #%d!", x); } } void main() { T t = new X; foo(&t.method); }
Mar 20
parent StarGrazer <Stary Night.com> writes:
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:

 [...]
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): [...]
Thanks.
Mar 20
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
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
parent reply StarGrazer <Stary Night.com> writes:
On Tuesday, 21 March 2017 at 15:01:43 UTC, ag0aep6g wrote:
 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.
Yes, but you changed it. I didn't have C. Initially this wasn't a problem.
 ----
 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.
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.
Mar 21
parent ag0aep6g <anonymous example.com> writes:
On 03/21/2017 04:09 PM, StarGrazer wrote:
 On Tuesday, 21 March 2017 at 15:01:43 UTC, ag0aep6g wrote:
 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.
Yes, but you changed it. I didn't have C. Initially this wasn't a problem.
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. [...]
 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