xs0 
| Nobody else has any thoughts on this proposal?
After some more thinking, it could be used with function parameters as well, so one could do this:
func(int a, short b);
func(long a, short b);
void main()
{
int i;
func(i, 5); // currently you need to do cast(short)5
// w/my proposal it would match the first func()
}
Additionally, it would really make sense to handle out and inout parameters in a special manner, because they only work with exact matching anyway.. For example:
func(out int a, short b);
func(out long b, float c);
void main()
{
long a;
short b=3;
func(a,b); // this should match the second func(), because
// the first one can't ever be used with long a
}
To sum up:
- the three-level matching is kept, but done per-parameter
- when out/inout parameters are used, functions that don't exactly match those parameters are not even considered
- if there is no exact match, and more than one non-exact match, it is still an error, like now, unless one function (and not more) exactly matches at least all parameters, where other functions have an exact match
The same goes for templates, except it has no out/inout parameters :)
These rules are almost as simple as the current system, yet handle a lot of cases where it's really obvious which overload should be used, but it currently isn't, because not all parameters are an exact match.. There are still no complicated rules no-one would know/understand, because there are still basically only two levels of matching - exact and non-exact, and it can't happen that an exact match on one parameter would mean more or less than an exact match on some other parameter (which I totally agree is confusing).
xs0
xs0 wrote:
> Hi!
>
> The current template matching system prevents code like this:
>
> ---
>
> template Blah(int a, alias B)
> {
> // do something with Blah!(a-1, B)
> }
>
> template Blah(int a:0, alias B)
> {
> // do something non-recursive
> }
>
> ---
>
> The problem is that Blah!(a-1, B) matches both templates when a==1, because the B parameter is not specialized in the second case. I see this as unnecessarily limiting.
>
> If matches are labeled as
>
> 0 - no match
> 1 - match
> 2 - exact match
>
> the current system would be described like this:
> 1) skip any template that includes a 0
> 2) if there's no template remaining, it's an error
> 3) if there's only one template remaining, it gets used
> 4) if there's more than one template remaining, a template must exist with only exact matches (just 2's), otherwise it is an error
>
> I propose that the last rule is changed, so that if there exists a template with better-or-equal score for each parameter than any other template, it is also allowed/not an error.
>
> So, Blah!(0, T) in the above example would produce scores (1,1) and (2,1), and so the second one would be chosen, because each score is greater or equal to scores in other templates..
>
> OTOH, if we had
>
> template Foo(int a, int b, alias C) ...
> template Foo(int a:0, int b, alias C) ...
> template Foo(int a, int b:0, alias C) ...
>
> Foo!(0, 0, T) would produce scores
>
> (1, 1, 1)
> (2, 1, 1)
> (1, 2, 1)
>
> And so it would be an error, because no template has every element of its score higher or equal to corresponding elements of scores in other templates. Adding template Foo(int a:0, int b:0, alias C) would resolve that problem, because its score would be (2, 2, 1).
>
> On a final note, it's funny that the above example works if B is not an alias, which I don't quite get - where's the major difference?
>
>
> xs0
|