2

Is there any performance hit associated with using type traits?

More precisely, are following evaluations constant time? And can the compilet optimize out some of following cases?

Consider such code:

template<typename T> void Function()
{
    if(std::is_pointer<T>::value == true)
        DoSmth();
}

Function<int*>();

Will the compiler optimize such code to become effectively (in generated binary) something like that?

template<> void Function<int*>()
{
        DoSmth();
}
Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
Mios
  • 247
  • 3
  • 11
  • 1
    You example does not reflect the question you start with. – rubenvb Dec 09 '14 at 12:07
  • 1
    @rubenvb In what way does it not? It looks like it does to me. –  Dec 09 '14 at 12:14
  • @hvd The question asks if type traits incur performance penalties. The example asks if a compiler can optimize constant (i.e. compile-time) conditional expressions. These are not the same thing. – rubenvb Dec 09 '14 at 12:15
  • @hvd My point is that this question has nothing to do with type traits. – rubenvb Dec 09 '14 at 12:26
  • 1
    @rubenvb I'm just not seeing that. It's not worth getting into a discussion about, though. If the OP agrees that the question is unclear, the OP will likely edit. If the OP does not see how the question is unclear, the OP will likely be unable to edit in a way that matches your expectations. Either way, it doesn't really depend on what you or I think. :) –  Dec 09 '14 at 12:29
  • @rubenvb Well, my questions was really constructed of two - whether this template structure is really ONLY compile-time, and if so - will the speciazlized version generated by compiler be optimized for this if(true). But again, SO mods are eager to mark questions. – Mios Dec 09 '14 at 12:34
  • @Mios I am not a mod, just an experienced user of the site. Your question as is does not clearly state that. At all. And to answer your questions then in so far they aren't answered by the dupes: yes and probably yes. – rubenvb Dec 09 '14 at 12:37

2 Answers2

4

The compiler is certainly allowed such an optimization, and I suspect that most will propagate the constant and eliminate the dead code if optimization is requested.

It seems more frequent and more idiomatic, however, to provide two separate functions, along the lines of:

template <typename T>
typename std::enable_if<std::is_pointer<T>::value>::type
Function()
{
    //  Pointer version...
}

template <typename T>
typename std::enable_if<!std::is_pointer<T>::velue>>:type
{
    //  Non pointer version...
}

Even before we had enable_if, it seemed more frequent to use overload resolution on helper functions, say by passing an extra argument which would match void const* (if it were a pointer) or ... (if it wasn't).

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 1
    Your suggestion of function overloads has an additional benefit: code inside an `if (std::is_pointer::value == true)` block needs to compile, it needs to be syntactically and semantically valid even if the type is not a pointer. Using separate function overloads avoids that problem. –  Dec 09 '14 at 12:21
  • @hvd Thanks for that. I knew, or at least suspected, that there was a reason the separate functions idiom was so wide spread. I think you've hit on it. (Now that you mention it: I suspect that most of the time I've done something like this, my code for one of the functions wouldn't have compiled for the other types.) – James Kanze Dec 09 '14 at 13:52
3

These days pretty much and decent compiler will remove the redundant flow control checks and generate the code you've specified in the second example.

Sean
  • 60,939
  • 11
  • 97
  • 136