Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

templates

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.
otherwise, it is such and such.

How can I do a similar test? Perhaps dynamic_cast?

Since the function I write is for my personal use I can rely on myself to supply only correct parameters, but why miss a chance to learn something? :)

like image 284
davka Avatar asked Aug 11 '10 13:08

davka


People also ask

What is template type parameter?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

Can we pass Nontype parameters to templates?

Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.

What are integral types in C++?

The integral types are: char , signed char , unsigned char -8 bits. short int , signed short int , and unsigned short int -16 bits. int , signed int , and unsigned int -32 bits. long int , signed long int , and unsigned long int -32 bits (OpenVMS)

How do I restrict a template type in C++?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.


1 Answers

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.

like image 107
Luc Touraille Avatar answered Sep 19 '22 02:09

Luc Touraille