This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Bug in template parameter type deduction
> With pleasure. I apologize for being not precise enough.
Thanks your your update. I'm still not convinced, so I guess I have to
come back to my request to discuss it on comp.std.c++ first.
> It compiles fine and even prints correct results:
Yes, that's corrrect.
> We have added the template parameter Property. Since it can't be
> deduced from the function parameter list, we specify its type
> explicitly. Paragraph 14.8.1 #2 allows us to omit the trailing
> parameter Object, which still can be deduced, since there is nothing
> about it that has changed against the case 1. Neither the number of
> candidate functions nor the way of type deduction is different.
Yes, that all true as well. What you are missing is the partial
ordering of function templates (14.5.5.2).
> After all, why hasn't the possible instantiation
>
> class provided<const object>& provide<const object>(const object &)
>
> hindered the compiler in the case 1? It should have had good reasons to
> consider it as a worse match that
>
> const class provided<object>& provide<object>(const object &)
>
> Probably because it's a more special match: const reference vs. reference in
> the function parameter list. Why doesn't the same argumentation work in the
> case 2?
When comparing viable candidates (13.3.3.), we first compare the
conversion sequence for the function arguments. Since the function
signatures are identical, we get no decision on
# for some argument j, ICSj(F1) is a better conversion sequence than
# ICSj(F2), or, if not that,
Next, we check whether one is a template and the other is not:
# F1 is a nontemplate function and F2 is a template function
# specialization, or, if not that,
Both are template specialization, so we still don't know which is
better.
# F1 and F2 are template functions, and the function template for F1
# is more specialized than the template for F2 according to the
# partial ordering rules described in 14.5.5.2, or, if not that,
So we perform partial ordering now. For that, we take the original
template declarations and try to compare them. Specifically,
# For each type template parameter, synthesize a unique type and
# substitute that for each occurrence of that parameter in the
# function parameter list, or for a template conversion function, in
# the return type.
...
# Using the transformed function parameter list, perform argument
# deduction against the other function template.
In your case 1) we find that template argument deduction succeeds in
one direction and not the other, so one template is more specialized
than the other - this is the one selected in your case 1.
In your case 2), partial ordering does not determine an order. No
matter what transformed parameter lists we use, we cannot deduce the
Property parameter in the partial ordering.
Therefore, we go back to 13.3.3 and check whether this is a
user-defined conversion; it is not. That's why we end up in 13.3.3/2
with two viable candidates
# If there is exactly one viable function that is a better function
# than all other viable functions, then it is the one selected by
# overload resolution; otherwise the call is illformed.
So the call is ill-formed. That may be counter-intuitive, and Martin
Sebor of RogueWave has raised a Defect Report for that, see
http://www.informatik.hu-berlin.de/~loewis/corer9.html#200
However, until there is some kind of official ruling on that, g++
won't change.
Regards,
Martin