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