Распаковка пакетов параметров в псевдонимах шаблонов

Я столкнулся с проблемой распаковки шаблонов переменных в псевдоним шаблона.

Следующий код работает с 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), но это должно провалиться? Вот некоторый контекст из Проблема языка C ++ # 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 пока у нас нет Ts, чтобы заменить в, и поэтому это должно быть обработано в календаре.

В настоящее время EDG и Clang отклоняют этот тестовый сценарий, жалуясь на слишком малое количество аргументов шаблона для A. G ++ тоже, но я подумал, что это ошибка. Однако в списке ABI Джон Спайсер утверждал, что он должен быть отклонен.

13

Решение

Об этом сообщают в gcc4.9 bugzilla:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498

Минимальный код для воспроизведения

template <typename T, typename ...>
using alias = T;

template <typename ...T>
using variadic_alias = alias<T...>;

using Fail = variadic_alias<int>;

int main() { }

Из объяснения от людей GCC — это не так очевидно, что это настоящая ошибка.
Это все еще обсуждение в gcc bugzilla и в DR 1430 (http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430) — краткая информация по вопросу выше.

10

Другие решения


По вопросам рекламы [email protected]