UFCS in generic libraries, silent hijacking, and compile errors.
aliak
something at something.com
Sat Mar 10 21:50:42 UTC 2018
What are the recommended guidelines for using/not using UFCS in
writing generic libraries?
I ask because if you have an internal generic free function that
you use on types in a generic algorithm via ufcs, then everything
works fine until the type being operated on has a member function
with a similar name.
If the signature matches the free function then the member
function is called instead of the free function (silently) and if
the signature does not match then you get a compiler error.
I.e.:
auto identity(T)(T t) { return t; }
auto fun(T)(T t) {
return t.identity;
}
void main() {
fun(3).writeln; // ok, print 3
struct S1 {}
fun(S1()).writeln; // ok, prints S1()
struct S2 { int identity() { return 77; } }
fun(S2()).writeln; // silent hijack, prints 77
struct S3 { int identity(int i) { return i + 2; } }
fun(S3()).writeln; // compile error
}
So the problem is that fun wants to use a utility function that
it knows about, but it turns out that T can hijack that internal,
private, utility if you use ufcs.
So basically, it seems like ufcs is fun until it doesn't work,
and it's not really obvious that you can run in to these problems
with ufcs.
I feel like the last case where it's a compilation error should
maybe be ok though, since the function being called is actually
undefined so ufcs should kick in. The problem as I understand it
is that ufcs is not part of an overload set. Making it part of it
would not prevent the silent hijack, but would remove the
compilation problem.
Is there something I'm not seeing as to why UFCS is not part of
the overload set, and is there a way other than not using UFCS to
prevent the silent hijacking?
Cheers
- Ali
More information about the Digitalmars-d-learn
mailing list