Рассмотрим следующий надуманный фрагмент кода:
template <class... > struct pack { };
template <class R, class T, class... Args>
int foo(pack<T>, Args...)
{
return sizeof(R);
}
template <class R, class T, class... Ts, class... Args>
int foo(pack<T, Ts...>, Args... args)
{
return foo<T>(pack<Ts...>{}, args...);
}
int main() {
// gcc: OK, clang: ambiguous
foo<int>(pack<int>{});
// gcc: ambiguous, clang: ambiguous
foo<int>(pack<int>{}, 0);
}
Оба gcc и clang принимают оба вызова, если 2-я перегрузка изменена, чтобы принять пакет из по меньшей мере 2 типов вместо пакета по меньшей мере одного типа:
template <class R, class T, class T2, class... Ts, class... Args>
int foo(pack<T, T2, Ts...>, Args... args)
{
return foo<T>(pack<T2, Ts...>{}, args...);
}
Если параметр не выводимого шаблона перемещается к параметру выведенного шаблона, то:
template <class... > struct pack { };
template <class R, class T, class... Args>
int foo(pack<R>, pack<T>, Args...)
{
return sizeof(R);
}
template <class R, class T, class... Ts, class... Args>
int foo(pack<R>, pack<T, Ts...>, Args... args)
{
return foo(pack<T>{}, pack<Ts...>{}, args...);
}
int main() {
// gcc ok with both, clang rejects both as ambiguous
foo(pack<int>{}, pack<int>{});
foo(pack<int>{}, pack<int>{}, 0);
}
Я ожидаю, что все вызовы будут в порядке в каждой версии этого. Каков ожидаемый результат приведенных выше примеров кода?