Проверьте целостный тип

Как я могу проверить, является ли тип параметра шаблона интегральным?

Я знаю, что я могу использовать std::is_integral<> в C ++ 11, чтобы сделать это. Здесь даже есть вопрос для этого.

Как проверить, что тип параметра этого шаблона является интегральным?

Я также знаю, что Boost предоставляет эту функцию. Меня интересует, как «вручную» сделать эту проверку.

Там нет конкретной проблемы, которую я пытаюсь решить. Это абстрактный вопрос о C ++.

0

Решение

Говоря вручную, вы должны сначала определить класс шаблона, который определяет, что-то
верно для false во время компиляции:

template<bool B>
struct bool_type {
static const bool value = B;
};

typedef bool_type<true> true_type;
typedef bool_type<false> false_type;

После этого вы начинаете определять класс черты со случаями по умолчанию и некоторыми случаями перенаправления:

template<typename T>
struct is_integral : false_type {};

template<typename T>
struct is_integral<const T> : is_integral<T> {};

template<typename T>
struct is_integral<volatile T> : is_integral<T> {};

Тогда ядро ​​будет проходить через создание экземпляра специализации шаблона для целочисленных типов вручную.

template<>
struct is_integral<int> : true_type {};

template<>
struct is_integral<long> : true_type {};

// etc

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

4

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

Это может быть «только ссылка» отвечу но имхо это ответит на вопрос,

Возможная реализация:

Линия 151 в 256 От GCC 4.8.1 Интернет-документы

См другие typedefs также закодировано выше Линия 151 .

1

Вы можете сделать что-то вроде этого, чтобы определить, является ли числовой тип целым или может иметь дробную часть. Этот код не будет компилироваться с нечисловыми типами, но может быть добавлено дополнительное метапрограммирование для фильтрации произвольных типов, если вы этого хотите. Это также может быть изменено, чтобы обеспечить «истинный» тип или «ложный» тип (например, ответ Раппца) вместо статического значения bool.

Я дал два способа проверить значение (а не тип). Один использует decltype для получения типа, а другой использует функцию шаблона. Функция может использоваться, если decltype недоступен, но ее результат, вероятно, может использоваться только во время выполнения (constexpr, вероятно, недоступен, если decltype нет).

И чтобы убедиться, что это понятно: макрос VALUE_IS_INTEGER и шаблонная функция value_is_integer не проверяют, является ли данное значение целым числом, они проверяют, является ли тип значения целочисленным.

#include <iostream>

template <typename T, bool IS_INTEGRAL = T(3)/T(2)<=T(1) || T(3)/T(2)>=T(2)>
struct IsIntegerTypeCheck {
static const bool is_integer = IS_INTEGRAL;
};

#define TYPE_IS_INTEGER(type)   (IsIntegerTypeCheck<type>::is_integer)
#define VALUE_IS_INTEGER(value) (IsIntegerTypeCheck<decltype(value)>::is_integer)

template <typename T> static bool value_is_integer(const T& value) {
return IsIntegerTypeCheck<T>::is_integer;
}

template <typename ST>
void dump_bool(ST message, bool value) {
std::cout << message << ' ' << (value ? "true" : "false") << "\n";
}

int main() {
static const bool   int_is_integer = TYPE_IS_INTEGER(int);
static const bool   float_is_integer = TYPE_IS_INTEGER(float);
static const long   unity = 1;
static const double tau = 3.1415925 * 2;
static const bool   unity_is_integer = VALUE_IS_INTEGER(unity);
static const bool   tau_is_integer = value_is_integer(tau);
dump_bool("int is integer:  ", int_is_integer);
dump_bool("float is integer:", float_is_integer);
dump_bool("unity is integer:", unity_is_integer);
dump_bool("tau is integer:  ", tau_is_integer);
return 0;
}
0
По вопросам рекламы [email protected]