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.

Reply via email to