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

в описании некоторой функции шаблона 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грал.