Address of UFCS call implicity converts to Delegate
Basile B. via Digitalmars-d
digitalmars-d at puremagic.com
Sun Apr 23 10:00:59 PDT 2017
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 ?
More information about the Digitalmars-d
mailing list