1

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?

Nathan Kleyn
  • 5,103
  • 3
  • 32
  • 49
Didier Trosset
  • 36,376
  • 13
  • 83
  • 122
  • 3
    "Note: I cannot use C++11, nor Boost." -- *Why?* Please tell me a good reason you can't use Boost. – Xeo Mar 27 '13 at 08:37
  • 1
    I'd like to have a *good reason*, but I've none, apart that current project cannot use it. – Didier Trosset Mar 27 '13 at 08:39
  • 3
    @DidierTrosset it looks like you will have to implement your own `is_integral` template. – juanchopanza Mar 27 '13 at 08:40
  • 2
    Copy parts of boost into your project. Problem solved. And if the whoever is responsible objects, `s/boost/potato/`. – Bartek Banachewicz Mar 27 '13 at 08:42
  • "Ask if in-house libraries are ok. If yes, copy Boost. All problems in IT, even management ones, can be solved with another level of indirection." -- Somebody who's name I unfortunately can't remember. – Xeo Mar 27 '13 at 08:45
  • 7
    Come on guys, it's not as simple as that. There are legal implications to using third party libraries in projects - I know we think it's silly but to the legal people this kind of thing is very important. And plenty of times there are people that decide Boost is too heavy a dependency. If "no Boost" is given as a requirement, the answer shouldn't be "use it anyway". – Ben Hymers Mar 27 '13 at 08:54
  • @Xeo Maybe you are refering to http://www.levelofindirection.com/ – Didier Trosset Mar 27 '13 at 08:57
  • 3
    @Ben: I don't buy that. Depending on Boost is like depending on your own project, since you can just copy it in. – Xeo Mar 27 '13 at 09:09
  • 5
    @Xeo: yeah, until your manager reviews it and goes "what the heck do you think you're doing". I'm sorry, sometimes we have to deal with this think called "the real world", which doesn't always behave the way you want it to. – jalf Mar 27 '13 at 09:59
  • @jalf as long as you can explain what the code is doing, i see no problem there. I mean, explain in general, because micromanaging should have its limits. – Bartek Banachewicz Mar 27 '13 at 10:00
  • 5
    @BartekBanachewicz: no? Perhaps you will, one day, when you encounter this *real world* of which I speak. If your boss tells you "do not f'ing use boost", and you then take the boost code and copy/paste it into your project, he's going to be pissed. Rightfully so. If your team has taken a decision to not use boost, then you stick with it, even if you don't like it. Because anything else is an asshole thing to do – jalf Mar 27 '13 at 10:02
  • 1
    @Bartek: That's hardly "micromanaging" – Lightness Races in Orbit Mar 27 '13 at 10:04
  • jalf has it exactly right - we may see no problem in using boost, but the "real world" has ways of forcing us not to. I've been told before that any third party open source code has to have gone through our legal department because the license usually specifies "no warranty", which apparently makes it very easy to sue us if it later turns out some of the code was unlawfully copied into the library. Regardless though, an answer involving removing some of the conditions from the question isn't a helpful answer. – Ben Hymers Mar 27 '13 at 11:38

1 Answers1

3

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.

Community
  • 1
  • 1
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510