Thread overview
Issue with typeof
Mar 20, 2017
StarGrazer
Mar 20, 2017
Moritz Maxeiner
Mar 20, 2017
Moritz Maxeiner
Mar 20, 2017
StarGrazer
Mar 21, 2017
ag0aep6g
Mar 21, 2017
StarGrazer
Mar 21, 2017
ag0aep6g
March 20, 2017
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.

March 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) {}
March 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;
        writefln("Hello, world #%d!", x);
    }
}

void main()
{
    T t = new X;
    foo(&t.method);
}
March 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:
>
>> [...]
>
> 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.
March 21, 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.
March 21, 2017
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.

March 21, 2017
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.