Given a struct S
with method foo
: Any of these expressions
&foo
&S.foo
&.S.foo
when they occur inside the struct they represent a delegate and not a function pointer. Is it okay to "extract" and use the function pointer from the delegate in this way:
struct S {
void function () fp;
void foo ()
{
fp = (&bar).funcptr;
}
void bar ()
{
fp = (&foo).funcptr;
}
auto fun () // invocation helper
{
if (! fp)
fp = (&foo).funcptr;
void delegate () dg;
dg.ptr = &this;
dg.funcptr = fp;
return dg ();
}
}
unittest {
S s;
s.fun;
s.fun;
}
In [1] Walter suggested to use a "lambda function" which reads (adopted to structs):
struct S {
:
void function (ref S) fp;
:
void foo () {
:
fun = function (ref S self) { return self.bar (); };
:
}
:
}
dmd and gdc optimize the lambda invocations away. Nonetheless the expression looks somewhat too big. To overcome this I tried to generate the function pointer outside of the struct:
auto funcptr (alias method) ()
{
return &method;
}
:
fun = funcptr!bar;
:
Which works but neither dmd nor gdc were able to optimize the additional function call away. So I replaced the function call with a value:
template funcptr (alias method) {
immutable funcptr = &method; // (*)
}
That code compiles under gdc 12.1 but I could not find any dmd version which compiles the code. All say
ptrtomethod.d(15): Error: non-constant expression `& bar`
Line 15 is the line I marked with (*)
. Any comments?
[1] https://www.digitalmars.com/articles/b68.html
Member Function Pointers in D