Question

While writing a C++ template function, I have to check that the variable type used by this function is integral. If it is the case, it should result in a compilation error.

template <class IT> void foo( IT first, IT last ) {
    // check here that *first has integral type.
}

The trouble I have, is that this function template parameter is not directly the type used, but an iterator type.

Unfortunately, I am currently in an environment where I cannot use C++11, nor Boost, so I will have to try reinventing this wheel myself.

I ended up testing that the type is integral by defining a pointer to an array, using the parameter an array size. This generates a compilation error if the parameter type is non integral.

template <class IT> void foo( IT first, IT last ) {
    int ( * fake_array_ptr )[*first]; // Error: size of array has non-integral type
}

My question is: Are there other more explicit ways to test whether a type is integral?

Was it helpful?

Solution

I ended up testing that the type is integral by defining a pointer to an array, using the parameter an array size. This generates a compilation error if the parameter type is non integral.

This is not portable. It can generate a compilation error even if the parameter type is integral, because array sizes must be integral constant expressions. It probably compiles currently because your compiler has the C99 variable length arrays as an extension and it is enabled by default.

There is a finite number of portable integral types. Explicit specializations for each one of these is a portable way of implementing is_integral in C++03.

template <typename T>
struct is_integral { static const bool value = false; };

template <>
struct is_integral<char> { static const bool value = true; };

template <>
struct is_integral<signed char> { static const bool value = true; };

template <>
struct is_integral<unsigned char> { static const bool value = true; };

template <>
struct is_integral<short> { static const bool value = true; };

// and so on

template <>
struct is_integral<unsigned long> { static const bool value = true; };

In order to cause a compilation error when this trait yields false, one would use static_assert in C++11, or BOOST_STATIC_ASSERT. There is a previous question about how to implement BOOST_STATIC_ASSERT on your own.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top