В temp.deduct.partial # 8 есть пример:
template<class... Args> void f(Args... args); // #1
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
f(); // calls #1
f(1, 2, 3); // calls #2
f(1, 2); // calls #3; non-variadic template #3 is more specialized
// than the variadic templates #1 and #2
Вызов № 1 тривиален, поскольку существует только одна жизнеспособная специализация.
Для вызова № 2, f₁
и f₂
являются жизнеспособными.Мы синтезируем f₁(X)
и f₂(X, Y)
.Затем мы делаем вывод типов в обоих направлениях.
Сначала f₂(X, Y)
против f₁(Args... args)
, что приводит к Args
, равному X, Y
.
Тогда f₁(X)
против пустоты f₂(T1 a1, Args... args)
, которая выводит T1
как X
, а Args
как пустое.
Таким образом, вычет успешен в обоих направлениях, и ни один не болееспециализированные, чем другие.
Можем ли мы сохранить temp.deduct.partial # 11 ?
Если после рассмотрения вышеизложенного шаблон функции Fпо крайней мере, такой же специализированный, как шаблон функции G и наоборот, и если G имеет пакет конечных параметров, для которого F не имеет соответствующего параметра, и если F не имеет пакета конечных параметров, то F более специализирован, чем G.
Не похоже, что это помогает.Пусть F=f₁, G=f₂
, тогда G
действительно имеет конечный пакет параметров, для которого F
не имеет соответствующего параметра.Но у F
есть конечный пакет параметров, так что это не относится.
Я что-то не так прочитал в стандарте или ответ может быть найден где-то еще?