UFCS functions with both pointers and refs

Mike Parker aldacron at gmail.com
Sun Dec 13 18:44:20 UTC 2020


On Sunday, 13 December 2020 at 18:31:54 UTC, Dave P. wrote:
> If I define a method on a type, then I can call it both through 
> a pointer and
> through a reference and the compiler does the right thing. Eg:
>
> struct Foo {
>     int x;
>     void fooey(){
>         x++;
>     }
>     void report(){
>         printf("%d\n", x);
>     }
> }
>
> int main(){
>     Foo f;
>     f.fooey;
>     Foo* pf = &f;
>     pf.fooey;
>     f.report; // prints 2
>     return 0;
> }
>
> However, if I define it as a free function and try to invoke it 
> via UFCS,
> it seems like I have to define it twice.
>
> struct Foo {
>     int x;
>     void report(){
>         printf("%d\n", x);
>     }
> }
>
> void fooey(Foo* f){
>     f.x++;
> }
> void fooey(ref Foo f){
>     f.x++;
> }
>
> int main(){
>     Foo f;
>     f.fooey;
>     Foo* pf = &f;
>     pf.fooey;
>     f.report; // prints 2
>     return 0;
> }
>
> Am I missing something or is this just how it has to work 
> generally?

These are two very different concepts.

Member functions have a hidden 'this' parameter as the first 
function parameter. For structs, it's a reference to the 
instance. Whether you call it through a pointer or a reference, 
that never changes: there's only one implementation of the 
function, the first parameter is always a reference to the 
instance.

Free functions do not belong to any type (hence the "free"). UFCS 
doesn't change that. UFCS is simply a convenience that rewrites 
`foo.func` as `func(foo)`. You aren't calling "through" a pointer 
or a reference. So if the first parameter is a pointer, you can't 
give it a reference, and vice versa.

> Do I have to write both and have one forward to the other for 
> more
> complicated functions?

For free functions, yes.



More information about the Digitalmars-d-learn mailing list