For short, write additional deduction guides like these:
template <typename T, typename... U>
array<T>(U...) -> array<T, sizeof...(U)>;
template <typename... T, typename... U>
tuple<T...>(T..., U...) -> tuple<T..., U...>;
This syntax looks like function template partial
specializations, but you know there is no such thing.
The semantics is easier to explain if the feature is
also enabled for function templates, where those
extra template arguments here are matched against
"prototype parameters". Function templates with
prototype parameters are not specializations, just
main templates. Let's say we have
template <typename T, typename U>
auto gcd(T, U); // 1
template <typename T, typename U>
auto gcd<T>(T, U); // 2
When user calls
gcd<int>('a', 'b');
, both #1 and #2 participate in overload resolution. #1
becomes
gcd<int, char>(int, char);
In #2, first, deduce T out of <int> using the rules of
template argument deduction, then substitute T = int
back into the template and obtain
gcd<int>(int, U);
, then deduce U out of the type of 'b' which is char, so
it's also
gcd<int, char>(int, char);
They are equally good, so a disambiguation rule kicks
in and prefers the one substituted from a function
template with prototype parameters.
Deduction guide's version works in the same way.
--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
_______________________________________________