Подтвердить что ты не робот

Почему этот вложенный вариационный шаблон является недопустимым аргументом?

Если я определяю шаблон struct Bar, который принимает аргумент шаблона:

template <template <int,bool,char> class>
struct Bar {};

Я могу создать экземпляр с помощью шаблона struct, например Zod:

template <int,bool,char> struct Zod {};
Bar<Zod> a;

Я также могу создать экземпляр с помощью вложенного шаблона struct, такого как JKL:

struct GHI {
  template <int,bool,char>
  struct JKL {};
};
Bar <GHI::JKL> b;

Почему я не могу создать экземпляр Bar с помощью вложенного вариационного шаблона struct, такого как DEF?:

template <typename ...Ts>
struct ABC {
  template <Ts ...>
  struct DEF {};
};

Bar<ABC<int,bool,char>::DEF> c;

g++ 4.9.2 жалуется на несоответствие типа/значения; в то время как сообщение Clang 3.4.2 сообщает, что аргумент шаблона шаблона имеет разные параметры шаблона, чем его соответствующий шаблонный шаблонный параметр.

4b9b3361

Ответ 1

Давайте дадим пакет параметров DEF имя для облегчения ссылки:

template <typename ...Ts>
struct ABC {
  template <Ts ... Values>
  struct DEF {};
};

Ключевым моментом здесь является то, что [temp.param]/p15, Ts... Values является как расширением пакета Ts, так и объявлением пакета параметров Values.

Если параметр шаблона является [...] декларацией параметра, объявляет пакет параметров (8.3.5), тогда шаблон-параметр является пакет параметров шаблона (14.5.3). Пакет параметров шаблона, который является Объявление параметра, тип которого содержит один или несколько нерасширенных пакетов параметров, является расширением пакета.

Так как DEF принимает пакет параметров не-типа, он не соответствует параметру шаблона шаблона, который не принимает пакеты ([temp.arg.template]/p3):

Аргумент шаблона соответствует шаблону-параметру шаблона P, когда каждый из параметров шаблона в template-parameter-list шаблона-аргумента, соответствующего шаблону класса или шаблону алиаса A, соответствует соответствующему шаблону параметр в списке параметров шаблона P. Два параметра шаблона если они имеют один и тот же вид (тип, не-тип, шаблон), для несимметричные шаблонные параметры, их типы эквивалентны (14.5.6.1), и для шаблонных шаблонов-параметров, каждый из их соответствующих Параметры шаблона совпадают, рекурсивно. Когда список параметров шаблона Ps содержит пакет параметров шаблона (14.5.3), пакет параметров шаблона будет соответствовать нулевому или более шаблону параметров или пакетов параметров шаблона в template-parameter-list A с тем же типом и формой, что и пакет параметров шаблона в P (игнорируя, является ли этот шаблон параметры - это пакеты параметров шаблонов).

Конечно, Values довольно странно для пакетов - для каждой специализации ABC, Values должно содержать фиксированное количество аргументов, но в соответствии с текущими правилами это еще пакет, поэтому правила для пакетов применяются.

Ответ 2

Как сказал Барри раньше:

ABC<int,bool,char>::DEF<4,true,'c'> foo

И сделайте попытку и работайте над онлайн-компилятором Coliru gcc 5.1 С++ 14 на этом сайте Компилятор:

#include <iostream>
 template <template <int,bool,char> class>
struct Bar {};
template <int,bool,char> struct Zod {};

Bar<Zod> a;

struct GHI {
  template <int,bool,char>
  struct JKL {};
};

Bar <GHI::JKL> b;

template <template <typename... Ts> class>
struct Base {};
template<typename... Ts>
struct Floor {};
Base<Floor> c;

template <typename... Ts>
struct ABC {
  template <Ts... val>
  struct DEF {};
};
ABC<int,bool,char>::DEF<4,true,'c'> foo;

Я сделал поиск и нашел этот список параметров шаблона.

Расширение пакета может появиться в списке параметров шаблона:

 template<typename... T> struct value_holder
{
    template<T... Values> // expands to a non-type template parameter 
    struct apply { };     // list, such as <int, char, int(&)[5]>
};

где я проверил некоторые вещи в компиляторе кода запуска: http://en.cppreference.com/w/cpp/language/parameter_pack но также я нашел эти шаблоны Ellipses и Variadic в visual studio 2013: https://msdn.microsoft.com/en-us/library/dn439779.aspx