template partial ordering rules underspecified
Nobody has claimed this yet.
- Dominant language
- TeX
- Stars
- 221
- Forks
- 813
- Avg merge
- 16h 4m
- Merged PRs (30d)
- 36
Description
There are several details in the template partial ordering rules that are underspecified. Both gcc and clang seem to agree on the algorithm for determining template ordering, but that algorithm doesn't actually appear in the standard. In no particular order:
Consistency of deduced values:
template <typename T> void foo(T, T); // (1)
template <typename T, typename U> void foo(T, U); // (2)
temp.deduct.type/2 makes it clear that there must be exactly one set of deduced values for the Ps. But there is no such statement in the partial ordering rule. The algorithm described only does pairwise P/A matching, so a synthesized call from (2) to (1) via foo(U{}, V{}) could succeed in deduction. Both gcc and clang agree that (1) is more specialized.
Type Synthesis Template Instantiation
template <typename T>
struct identity { using type = T; };
template<typename T> void bar(T, T ); // (1)
template<typename T> void bar(T, typename identity<T>::type ); // (2)
Here, if synthesized for (2) Unique2 and typename identity<Unique2>::type == Unique2, then type deduction would succeed in both directions and the call bar(0,0) would be ambiguous. However, it seems that both compilers instead simply treat typename identity<Unique2>::type as Unique2_b, thus making template deduction from (2) to (1) fail (based on the implied missing Consistency rule).
Non-Deduced Context Omission
Same as previous example, but now define:
template <typename T> struct identity; template <> struct identity<int> { using type = int; };
With no template instantiation during synthesis and consistency, the (2) ==> (1) deduction fails. But if we consider the (1) ==> (2) call, we'd match T against Unique1 and then have the non-deduced context typename identity<Unique1>::type to match against Unique1, but that would be a substitution failure. It seems that the approach taken by gcc and clang (both of which prefer (1) here) is to ignore the non-deduced context argument, as long as that parameter type is deduced from a different template parameter type that did get matched.
The approaches that gcc/clang take make sense - but those rules should be spelled out in the standard.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the three examples in this issue and compare the stated behavior with the template partial ordering rules in the C++ standard. Review how GCC and Clang handle consistency of deduced values, synthesized types, and non-deduced contexts. Done means the missing rules are resolved and explicitly specified in the standard.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100