Я не смог найти ответ на свою проблему, поэтому я отправил его как вопрос. Я делаю небольшой пример, чтобы объяснить это:
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).
использование техника черт:
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);
}
Ключ — Сфина. Вы должны объявить вспомогательный класс на основе типа хранилища и предоставить определение для одного из двух. Таким образом, если специализация существует, вы знаете во время компиляции, какой тип хранилища у вас есть (тот, для которого вы предоставили определение), и если замена не удалась (что не является ошибкой, SFINAE), вы находитесь в другом случае.