This implementation matches GCC behavior in that temp.func.order p6.2.1 is not implemented [1]. I reached out to the GCC author to confirm that some changes elsewhere to overload resolution are probably needed, but no solution has been developed sufficiently [3].
Most of the wordings are implemented straightforwardly. However,
for temp.func.order p6.2.2 "... or if the function parameters that positionally correspond between the two templates are not of the same type", the "same type" is not very clear ([2] is a bug related to this). Here is a quick example
template <C T, C U> int f(T, U); template <typename T, C U> int f(U, T); int x = f(0, 0);
Is the U and T from different fs the "same type"? The answer is NO even though both U and T are deduced to be int in this case. The reason is that U and T are dependent types, according to temp.over.link p3, they can not be the "same type".
To check if two function parameters are the "same type":
- For function template: compare the function parameter canonical types and return type between two function templates.
- For class template/partial specialization: by temp.spec.partial.order p1.2, compare the injected template arguments between two templates using hashing(TemplateArgument::Profile) is enough.
[1] https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=57b4daf8dc4ed7b669cc70638866ddb00f5b7746
[2] https://github.com/llvm/llvm-project/issues/49308
[3] https://lists.isocpp.org/core/2020/06/index.php#msg9392
Fixes https://github.com/llvm/llvm-project/issues/54039
Fixes https://github.com/llvm/llvm-project/issues/49308 (PR49964)
You can remove this bullet from when I partially implemented this paper :)