template <typename T>
void call(T) { //#1
std::cout << "1" << std::endl;
}
template <typename T, typename...Args>
void call(T, Args...) { //#2
std::cout << "2" << std::endl;
}
When I call the function like this
call(10);
GCC, Clang, and MSVC all use #1.
However, the partial ordering rule in the standard says:
If the parameter-declaration corresponding to Pi is a function parameter pack, then the type of its declarator-id is compared with each remaining parameter type in the parameter-type-list of A. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. During partial ordering, if Ai was originally a function parameter pack:
(10.1) if P does not contain a function parameter type corresponding to Ai then Ai is ignored;
(10.2) otherwise, if Pi is not a function parameter pack, template argument deduction fails.
When we deduce #1 from #2, with T, Args...
as A, T
as P, P does not contain a template argument corresponding to Args...
. Args...
is ignored, so #1 can be deduced from #2 successfully.
Then the deducing #2 from #1, with T
as A and T, Args...
as P, also successfully results in T = T, Args... = {}
.
Therefore, according to the partial ordering rules, when call call(10)
, the compiler should be giving the ambiguous error, but in fact all compiler called #1, why is this?
<>
with single quotes inside text, otherwise it is not visible, fixed that for you, but not sure if I missed some – 463035818_is_not_a_number