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.