Как проверить, что тип параметра этого шаблона является интегральным? - PullRequest
6 голосов
/ 11 августа 2010

В описании некоторой функции шаблона std я увидел что-то вроде:

если параметр шаблона имеет целочисленный тип, поведение такое-то и такое-то.
в противном случае, он такой-то и такой-то.

Как я могу сделать аналогичный тест? Возможно dynamic_cast?

Поскольку функция, которую я пишу, предназначена для личного использования, я могу рассчитывать на то, что предоставлю только правильные параметры, но зачем упускать шанс что-то узнать? :)

Ответы [ 4 ]

4 голосов
/ 11 августа 2010

В дополнение к другим ответам следует отметить, что тест может использоваться во время выполнения, но также и во время компиляции, чтобы выбрать правильную реализацию в зависимости от того, является ли тип целым или нет:

Рабочая версия:

// 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 компилятор "выберет" правильную реализацию в зависимости от того, является ли параметр шаблона целым или нет.

3 голосов
/ 11 августа 2010

Одна возможность :

#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<> для определения действия.

2 голосов
/ 18 ноября 2016

Если вы не можете использовать функции C ++ 11, std::numeric_limits<T>::is_integer делает то же самое , что и std::is_integral<T>::value, и доступно с C ++ 98.

Обратите внимание, что версия 98 - это inte ger , а не inte gral .

1 голос
/ 11 августа 2010

Boost.TypeTraits предоставляет is_integral <> (), как описано в другом ответе, если ваш компилятор еще не поддерживает функции C ++ следующего стандарта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...