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