You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using the resulting types P and A, the deduction is then done as described in [temp.deduct.type].
[temp.deduct.type] p1 says
an attempt is made to find template argument values (a type for a type parameter, a value for a non-type parameter, or a template for a template parameter) that will make P, after substitution of the deduced values (call it the deduced A), compatible with A.
[temp.func.order] p3 says
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.
Take #1 as the argument template and #2 as the parameter template. Assume the unique type for T in #1 is TUnique1, hence A is A<TUnique1, TUnique1>, which compares with P that is A<T, std::remove_reference_t<decltype(std::declval<T>())>>, the first T in P is deduced to TUnique1, according to [temp.deduct.type] p4, the second T in P uses the value deduced for the first T. Back to [temp.deduct.type] p1, the result of the substitution is A<TUnique1, TUnique1> because std::remove_reference_t<decltype(std::declval<T>())> is T for any type T. The deduction of P from A success. Again,take #1 as the parameter template and #2 as the argument template, with the similar reason, the deduction of P from A success. We expect the call would be ambiguous, however, most implementations chose #1.
The call prints #1 but A<int,int> is ambiguous. However, the partial ordering of the class partial specializations should be equivalent to partial ordering of the function templates.
The text was updated successfully, but these errors were encountered:
xmh0511
changed the title
[temp.deduct.partial] The substitution in patial ordering for function templates
[temp.deduct.partial] The substitution in partial ordering for function templates
May 6, 2022
xmh0511
changed the title
[temp.deduct.partial] The substitution in partial ordering for function templates
[temp.deduct.partial] The substitution in partial ordering for function/class templates
May 6, 2022
xmh0511
changed the title
[temp.deduct.partial] The substitution in partial ordering for function/class templates
[temp.deduct.partial] The unclear points in partial ordering for function/class templates
May 6, 2022
Another vague point is whether the instantiation is performed for determining the actual type of argument template and the deduced A. According to the behavior of implementations, the instantiation is not performed for the type of the argument template in both partial orderings of function template and class template. For the deduced A, the instantiation is performed for the function template but is not performed for the class template. Specifically, for the unique type Unique
The A will be A<Unique, decltype(Unique{})> rather than A<Unique, Unique>(after instantiation). Assume A<T,T> is A with a synthesized unique type Unique2 and A<T, decltype(T{})> is P, for partial ordering of function template, the instantiation may happen for it after deducing A<T, decltype(T{})> from A<Unique2, Unique2>, the deduced A is A<Unique2, Unique2> that is compatible with A. For partial ordering class template, the instantiation is not performed(i.e. remain its original form), the deduced A is ``A<Unique2, decltype(Unique2{})>, which is not compatible with A<Unique2, Unique2>`.
The above conclusion is inspired by the behavior of implementations and the answers of @zygoloid. This part is vague in the standard.
BUT the deduced A' is not always possible to instantiate the final type to determine whether A' is compatible with A. Such as A<T, decltype(fun(T))>, different types of the argument will produce the different return types(if fun is overload set). In this case, it is not possible to determine the return type of fun when giving a unique type that is not concrete. In summary, whether the deduction success and how compatible are just vague in the partial ordering of both function templates and class templates.
[temp.deduct.partial] p8 says
[temp.deduct.type] p1 says
[temp.func.order] p3 says
Consider this example:
Take
#1
as the argument template and#2
as the parameter template. Assume the unique type forT
in#1
isTUnique1
, henceA
isA<TUnique1, TUnique1>
, which compares withP
that isA<T, std::remove_reference_t<decltype(std::declval<T>())>>
, the firstT
inP
is deduced toTUnique1
, according to [temp.deduct.type] p4, the secondT
inP
uses the value deduced for the firstT
. Back to [temp.deduct.type] p1, the result of the substitution isA<TUnique1, TUnique1>
becausestd::remove_reference_t<decltype(std::declval<T>())>
isT
for any typeT
. The deduction ofP
fromA
success. Again,take#1
as the parameter template and#2
as the argument template, with the similar reason, the deduction ofP
fromA
success. We expect the call would be ambiguous, however, most implementations chose#1
.Consider a contrast example:
For any type
T
, the result of the substitution oftypename Wrapper<T>::type
isT
. The call is ambiguous for a similar reason as above, at this time, implementations agree the call is ambiguous. More vague in partial ordering can be found herehttps://stackoverflow.com/questions/31394260/template-partial-ordering-why-does-partial-deduction-succeed-here
https://stackoverflow.com/questions/42416993/class-template-specialization-partial-ordering-and-function-synthesis
The subject of the second question can be simplified as
The call prints
#1
butA<int,int>
is ambiguous. However, the partial ordering of the class partial specializations should be equivalent to partial ordering of the function templates.The text was updated successfully, but these errors were encountered: