Как проверить, что тип параметра шаблона является интегральным?
в описании некоторой функции шаблона std я увидел что-то вроде:
если параметр шаблона имеет интегральный тип, поведение такое-то.
иначе - то и то.
Как я могу сделать аналогичный тест? Возможно, операцию dynamic_cast?
поскольку функция, которую я пишу, предназначена для моего личного использования, я могу рассчитывать на себя, чтобы предоставить только правильные параметры, но зачем упускать шанс узнать что-то? :)
4 ответов
в дополнение к другим ответам следует отметить, что тест может использоваться во время выполнения, но и во время компиляции для выбора правильной реализации в зависимости от того, является ли тип интегральным или нет:
runtime версия:
// Include either <boost/type_traits/is_integral.hpp> (if using Boost)
// or <type_traits> (if using c++1x)
// In the following, is_integral shoudl be prefixed by either boost:: or std::
template <typename T>
void algorithm(const T & t)
{
// some code
if (is_integral<T>::value)
{
// operations to perform if T is an integral type
}
else
{
// operations to perform if T is not an integral type
}
// some other code
}
однако это решение может быть улучшено, когда реализация алгоритма в значительной степени зависит от теста. В этом случае у нас был бы тест в верхней части функции, а затем большой then
блок и большая else
заблокировать. Общий подход в этом случае-перегрузить функцию и заставить компилятор выбрать правильную реализацию с помощью SFINAE. Простой способ сделать это-использовать boost::enable_if
:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
template <typename T>
typename boost::enable_if<boost::is_integral<T> >::type
algorithm(const T & t)
{
// implementation for integral types
}
template <typename T>
typename boost::disable_if<boost::is_integral<T> >::type
algorithm(const T & t)
{
// implementation for non integral types
}
при использовании algorithm
функция, компилятор "выберет" правильную реализацию в зависимости от того, является ли параметр шаблона интегральным или нет.
#include <type_traits>
#include <iostream>
struct trivial
{
int val;
};
int main()
{
std::cout << "is_integral<trivial> == " << std::boolalpha
<< std::is_integral<trivial>::value << std::endl;
std::cout << "is_integral<int> == " << std::boolalpha
<< std::is_integral<int>::value << std::endl;
std::cout << "is_integral<float> == " << std::boolalpha
<< std::is_integral<float>::value << std::endl;
return (0);
}
Итак, вы используете std::is_integral<>
для определения действия.
импульс.TypeTraits предоставляет is_integral (), как описано в другом ответе, если ваш компилятор еще не поддерживает функции C++ следующего стандарта.
Если вы не можете использовать C++11 особенности, std::numeric_limits<T>::is_integer
тут то же самое as std::is_integral<T>::value
, и доступен с C++98.
обратите внимание, что версия 98 является integer, не inteграл.