Ответ 1
Это компилируется в GCC 4.8, но не работает в GCC 4.9, что свидетельствует о том, что оно связано с DR1430 и отчет об ошибке # 59498. Исправление, предложенное Роем Хрихфилдом, является тем же самым, что и у вас:
Rewriting the code to use a struct succeeds:
template <typename T, typename ...>
struct alias { using type = T; };
template <typename ...T>
using variadic_alias = typename alias<T...>::type;
Кроме того, Джейсон Меррилл уточняет, почему он должен потерпеть неудачу:
На самом деле, нет, это проблема Core 1430; нет способа mangle variadic_alias без упоминания имени псевдонима шаблоны в качелях, и они должны быть полностью прозрачный. Это работает только в 4.8 случайно, потому что проверка отключено для выпуска.
В отчете об ошибках больше не обсуждается, поэтому мы можем обратиться к DR1430:
Первоначально расширение пакета не могло расширяться до фиксированной длины список параметров шаблона, но это было изменено в N2555. Это работает отлично подходит для большинства шаблонов, но вызывает проблемы с шаблонами псевдонимов.
В большинстве случаев шаблон псевдонима прозрачен; когда он используется в Шаблон мы можем просто заменить в зависимых аргументах шаблона. Но это не работает, если идентификатор шаблона использует расширение пакета для невариантные параметры. Например:
template<class T, class U, class V> struct S {}; template<class T, class V> using A = S<T, int, V>; template<class... Ts> void foo(A<Ts...>);
Невозможно выразить A в терминах S, поэтому нам нужно провести на А, пока мы не заменим Ts, и, следовательно, должен быть обработан в mangling.
В настоящее время EDG и Clang отклоняют этот тест, жалуясь на слишком несколько аргументов шаблона для A. g++ тоже, но я думал, что это Жук. Однако в списке ABI Джон Спайсер утверждал, что это должно быть отвергнуто.
(См. также выпуск 1558.)
Заметки из собрания в октябре 2012 года:
По мнению CWG, это использование должно быть запрещено, запрет использования шаблона псевдонима, когда зависимый аргумент не может просто подставляться непосредственно в идентификатор типа.
Дополнительное примечание, апрель, 2013:
В другом примере рассмотрим:
template<class... x> class list{}; template<class a, class... b> using tail=list<b...>; template <class...T> void f(tail<T...>); int main() { f<int,int>({}); }
При обработке этого примера существует дисперсия реализации.
В других словах это постоянная проблема без какого-либо разрешения (AFAIC).