При разрешении двусмысленностей между перегрузками шаблонов функций выполняется частичное упорядочение (см. здесь для некоторых объяснений). На этом веб-сайте мы также узнаем, что
В случае привязки, если один шаблон функции имеет трейлинг-параметр pack, а другой нет, тот, у которого отсутствует параметр, является считается более специализированным, чем тот, у которого есть пустой пакет параметров.
Теперь интересно, какой именно трейлинг-пакет параметров. Что, если какой-либо из
template<class ...> struct tuple { /* ... */ };
template<class T, class...Ts> void foo(tuple<T,Ts...>);
template<class T, class...Ts> void bar(T, Ts...);
есть, а что нет и почему? Заметим также, что кланг считает
template<class T> void f(tuple<T>);
template<class T, class...Ts> void f(tuple<T,Ts...>);
int main()
{ f(tuple<int>()); } // ambiguous call?
неоднозначно, подразумевая, что foo
не имеет завершающего пакета параметров.