cplusplus / cplusplus/draft

[temp.deduct.partial] The unclear points in partial ordering for function/class templates

Open
#5,454 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TeX
Stars
221
Forks
813
Avg merge
16h 4m
Merged PRs (30d)
36

Description

[temp.deduct.partial] p8 says

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.

Consider this example:

template<class T, class U>
struct A{};

template<class T>
void fun(A<T,T>){
    std::cout<<"#1\n";
}

template<class T>
void fun(A<T, std::remove_reference_t<decltype(std::declval<T>())>>){
     std::cout<<"#2\n";
}

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.

Consider a contrast example:

template<class T>
struct Wrapper{
    using type = T;
};

template<class T, class U>
struct A{};

template<class T>
void fun(A<T, typename Wrapper<T>::type>){
    std::cout<<"#1\n";
}

template<class T>
void fun(A<T, std::remove_reference_t<decltype(std::declval<T>())>>){
     std::cout<<"#2\n";
}

For any type T, the result of the substitution of typename Wrapper<T>::type is T. 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 here
https://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

template<class T, class U>
struct A{};

// template<class T>
// struct A<T,T>{};

// template<class T>
// struct A<T, decltype(T{})>{};

template<class T>
void fun(A<T,T>){
    std::cout<<"#1\n";
}

template<class T>
void fun(A<T, decltype(T{})>){
    std::cout<<"#2\n";
}
int main(){
   // A<int,int> c;  
   fun(A<int,int>{});
}

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.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with [temp.deduct.partial], [temp.deduct.type], and [temp.func.order], then reproduce the two function-template examples and the class-template contrast described in the issue. Compare the observed partial-ordering results with the cited rules and related Stack Overflow cases. Done means the ambiguity is resolved in the standard wording or the issue is clearly documented with the intended interpretation.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.