C ++ шаблон метапрограммирования статическая проверка типов

Я не смог найти ответ на свою проблему, поэтому я отправил его как вопрос. Я делаю небольшой пример, чтобы объяснить это:

enum STORAGE_TYPE
{
CONTIGUOUS,
NON_CONTIGUOUS
};

template <typename T, STORAGE_TYPE type=CONTIGUOUS>
class Data
{
public:
void a() { return 1; }
};

// partial type specialization
template <typename T>
class Data<T, NON_CONTIGUOUS>
{
public:
void b() { return 0; }
};

// this method should accept any Data including specializations…
template <typename T, STORAGE_TYPE type>
void func(Data<T, type> &d)
{
/* How could I determine statically the STORAGE_TYPE? */
#if .. ??
d.a();
#else
d.b();
#endif
}int main()
{
Data<int> d1;
Data<int, NON_CONTIGUOUS> d2;

func(d1);
func(d2);

return 0;
}

Обратите внимание, что
(1)
Я не хочу специализацию «func», поскольку это может решить ее, но я просто хочу иметь 1 универсальный метод «func» с внутренними статическими условиями «if» для выполнения кода.
(2) и я бы предпочел решение со стандартным C ++ (не C ++ 0x или boost).

3

Решение

использование техника черт:

template <typename T, STORAGE_TYPE type>
struct DataTraits {
static void callFunction(Data<T, type> &d)
{
d.a();
}
};

template <typename T>
struct DataTraits<T,NON_CONTIGUOUS> {
static void callFunction(Data<T, NON_CONTIGUOUS> &d)
{
d.b();
}
};// this method should accept any Data including specializations…
template <typename T, STORAGE_TYPE type>
void func(Data<T, type> &d)
{
/* How could I determine statically the STORAGE_TYPE? */
DataTraits<T,type>::callFunction(d);
}
5

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

Ключ — Сфина. Вы должны объявить вспомогательный класс на основе типа хранилища и предоставить определение для одного из двух. Таким образом, если специализация существует, вы знаете во время компиляции, какой тип хранилища у вас есть (тот, для которого вы предоставили определение), и если замена не удалась (что не является ошибкой, SFINAE), вы находитесь в другом случае.

0

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