Вариативный шаблон С++ для замены списка типов

Я хотел бы использовать вариативные шаблоны, чтобы заменить этот приведенный ниже стандартный код списка типов. Также обратите внимание, что в качестве типа используется int. Я пытаюсь включить строго типизированные перечисления, как определено в С++ 11, поэтому я хочу заменить int HEAD типом параметра шаблона.

template <int HEAD, class TAIL>
struct IntList {
  enum { head = HEAD };
  typedef TAIL tail;
};

struct IntListEnd {};

#define LIST1(a) IntList<a,IntListEnd>
#define LIST2(a,b) IntList<a,LIST1(b) >
#define LIST3(a,b,c) IntList<a,LIST2(b,c) >
#define LIST4(a,b,c,d) IntList<a,LIST3(b,c,d) >

Вот по какой дороге я пытался идти:

template <class T, T... Args> 
struct vlist;

template <class T, T value, T... Args>
struct vlist {
  T head = value;
  bool hasNext() { 
    if (...sizeof(Args) >=0 ) 
      return true; 
  }
  vlist<T,Args> vlist;
  vlist getNext () { 
    return vlist;
  }
};

template <class T> 
struct vlist { };

И пример инициализации этого I должен быть похож на приведенный ниже:

enum class FishEnum { jellyfish, trout, catfish };
vlist <FishEnum, FishEnum::jellyfish, FishEnum::trout, FishEnum::catfish> myvlist;

Я искал на форумах хороший пример структуры шаблона, которая безуспешно может принимать тип и значения типа. Любые предложения о том, куда идти отсюда? Я вставил свои ошибки компиляции ниже из приведенного выше кода,

note: previous declaration 'template<class T, T ...Args> struct vlist' used 2 template parameters
template <class T, T... Args> struct vlist;
                                     ^
error: redeclared with 1 template parameter
struct vlist { };
       ^
note: previous declaration 'template<class T, T ...Args> struct vlist' used 2 template parameters
template <class T, T... Args> struct vlist;

person user355543    schedule 10.09.2013    source источник


Ответы (1)


Вам не хватает ряда расширений и специализаций параметров для базового шаблона. Следует иметь в виду одну вещь: после того, как вы объявили базовый шаблон, все остальные шаблоны должны быть специализацией этой базы:

// Base template
template <class T, T... Args> 
struct vlist;

// Specialization for one value
template <typename T, T Head>
struct vlist<T, Head>
{
    T head = Head;
    constexpr bool has_next() const { return false; }
};

// Variadic specialization
template <class T, T Value, T... Args>
struct vlist<T, Value, Args...> 
{
    T head = Value;

    constexpr bool has_next() const { return true; }

    constexpr vlist<T, Args...> next() const
    { 
        return vlist<T, Args...>();
    }
};
person Yuushi    schedule 10.09.2013