Thread overview
Issue with typeof
Mar 21
ag0aep6g
Mar 21
ag0aep6g
March 20
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
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
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
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
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
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
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.