У меня возникла проблема с распаковкой вариационных шаблонов в псевдоним шаблона.
Следующий код работает с Clang 3.4 и GCC 4.8, но не с GCC 4.9:
template <typename T, typename...>
using front_type = T;
template <typename... Ts>
struct foo
{
using front = front_type<Ts...>;
};
GCC 4.9 жалуется:
test.cc:7:37: error: pack expansion argument for non-pack parameter 'T' of alias template 'template<class T, class ...> using front_type = T'
using front = front_type<Ts...>;
^
test.cc:1:15: note: declared here
template <typename T, typename...>
^
Существует зарегистрированная ошибка GCC (# 59498), но должно ли это провалиться? Вот какой-то контекст из проблемы с основным ядром С++ # 1430, "расширение пакета в список параметров шаблона фиксированных псевдонимов" :
Первоначально расширение пакета не могло расширяться в список параметров шаблона фиксированной длины, но это было изменено в 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<Ts...>
в терминахS
, поэтому нам нужно удерживать наA
, пока мы не заменимT
, и, следовательно, его нужно обработать в режиме mangling.В настоящее время EDG и Clang отклоняют этот тест, жалуясь на слишком мало аргументов шаблона для A. g++, но я думал, что это ошибка. Однако в списке ABI Джон Спайсер утверждал, что его следует отклонить.