On Sunday, 23 April 2017 at 16:32:06 UTC, Jonathan Marler wrote:
This feels like a natural extension to existing semantics. It
doesn't require new syntax and serves as a solution to some
issues when working with delegates.
Say some API wants a delegate like this: void delegate(string
arg)
With this feature, you could take a function like this:
void myCoolFunction(MyClassObject obj, string arg)
{
// ...
}
and the following would have the same delegate type:
&myClassObject.myCoolFunction // type is void delegate(string
arg)
This of course wouldn't work for all functions. The first
parameter of the function would need to have the same calling
convention as the "this" parameter for a "delegate".
void cantBecomeDelegate(SomeBigStructType s)
{
}
&myStruct.cantBecomeDelegate // Error
error: cannot convert UFCS call to delegate because the first
parameter of function 'cantBecomeDelegate' is too large.
Consider adding "ref" to the first parameter or making it a
pointer.
To fix this you could do something like this:
void canBecomeDelegate(ref SomeBigStructType s)
{
}
&myStruct.canBecomeDelegate // OK!
What would be the usage of this ?
Actually i think i see the ABI trick you want to use. And it
works:
==================
import std.stdio;
alias ProtoD = void delegate(size_t);
alias ProtoF = void function(size_t);
class Foo{size_t a;}
extern(C) void pseudoMemberFunc(Foo foo, size_t a)
{ foo.a = a;}
void main()
{ Foo foo = new Foo;
// under the hood it's what would make
"&foo.pseudoMemberFunc;"
ProtoD dg;
dg.funcptr = cast(ProtoF) &pseudoMemberFunc;
dg.ptr = cast(void*) foo;
// close the hood carefully
dg(42);
writeln(foo.a);
}
It works in extern(C) only because of parameter order.
==================
But:
1/ It's dangerous because then nothing guarantees anymore that
.funcptr is a n actual member function.
2/ Why not just a member function ?