How to check that template's parameter type is integral?

前端 未结 4 629
南笙
南笙 2021-01-12 09:11

In the description of some std template function I saw something like:

if the template parameter is of integral type, the behavior is such and such.

相关标签:
4条回答
  • 2021-01-12 09:32

    If you are unable to use C++11 features, std::numeric_limits<T>::is_integer does the same thing as std::is_integral<T>::value, and is available with C++98.

    Note that the 98 version is integer, not integral.

    0 讨论(0)
  • 2021-01-12 09:46

    Boost.TypeTraits provides is_integral<>(), as described in another response, if your compiler does not yet support C++ features of the next standard.

    0 讨论(0)
  • 2021-01-12 09:47

    In addition to the other answers, it should be noted that the test can be used at runtime but also at compile-time to select the correct implementation depending on wether the type is integral or not:

    Runtime version:

    // 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
    }
    

    However, this solution can be improved when the implementation of the algorithm greatly depends on the test. In this case, we would have the test at the top of the function, then a big then block and a big else block. A common approach in this case is to overload the function and make the compiler select the correct implementation using SFINAE. An easy way to do this is to use 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
    }
    

    When invoking the algorithm function, the compiler will "select" the correct implementation depending on wether the template parameter is integral or not.

    0 讨论(0)
  • 2021-01-12 09:54

    One possibility:

    #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); 
    } 
    

    So you then use std::is_integral<> to determine the action.

    0 讨论(0)
提交回复
热议问题