Реализация Loki IndexOf для TypeList

Я реализовывал TypeList на основе Loki, основываясь на чтении из:

http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s09.html

и увидел этот код с сайта для IndexOf (чтобы найти индекс типа в списке типов):

template <class T>
struct IndexOf< NullType, T>
{
    enum { value = -1 };
};

template <class T, class Tail>
struct IndexOf< Typelist<Head, Tail>, T>
{
private:
    enum { temp = IndexOf<Tail, T>::value };
public:
    enum { value = (temp == -1) ? -1 : 1+temp };
};

Не похоже, что это сработает, потому что нигде я не вижу чего-то, сравнивающего T, поскольку список рекурсивно просматривается. В моей реализации это выглядит так:

template<typename Tlist, typename T>
struct IndexOf
{
private:
  static const int temp = IndexOf<typename Tlist::Tail, T>::value;
public:
  static const int value = (temp == -1) ? -1 : 1 + temp;
};

template<typename T>
struct IndexOf<NullType, T>
{
  static const int value = -1;
};

и, фактически, всегда возвращает -1. Если я думаю об этом, представьте, что у вас есть TypeList; тогда Tail будет NullType, поэтому temp будет -1 по специализации, а затем значение будет -1..even, если Head был char и я ожидал бы ноль. Что мне здесь не хватает?

Спасибо


Моя реализация Typelist просто:

template<typename H, typename T>
struct Typelist
{
  typedef H Head;
  typedef T Tail;
};

Я предполагаю, что это не Локис, но с ответом Джоэла я понял, что это работает для меня:

template<typename Head, typename Tail, typename T>
struct IndexOfImpl
{
private:
  static const int temp = IndexOfImpl<typename Tail::Head, typename Tail::Tail, T>::value;
public:
  static const int value = (temp == -1) ? -1 : temp + 1;
};

template<typename T, typename Tail>
struct IndexOfImpl<T, Tail, T>
{
  static const int value = 0;
};

template<typename T>
struct IndexOfImpl<T, NullType, T>
{
  static const int value = 0;
};

template<typename Head, typename T>
struct IndexOfImpl<Head, NullType, T>
{
  static const int value = -1;
};

template<typename Tlist, typename T>
struct IndexOf
{
 public:
  static const int value = IndexOfImpl<typename Tlist::Head, typename Tlist::Tail, T>::value;
};

1 ответ

Решение

Должно быть:

template <class T>
struct IndexOf< NullType, T>
{
    enum { value = -1 };
};

template <class T, class Head, class Tail>
struct IndexOf< Typelist<Head, Tail>, T>
{
private:
    enum { temp = IndexOf<Tail, T>::value };
public:
    enum { value = (temp == -1) ? -1 : 1+temp };
};

template <class T, class Tail>
struct IndexOf< Typelist<T, Tail>, T>
{
public:
    enum { value = 0 };
};

Вы пытаетесь найти T у некоторого Head в рекурсивной кодировке списка.

Другие вопросы по тегам