title: What do compilers do with compile-time branching?
body: <p><strong>EDIT:</strong> I took the "if/else" case as an example that can sometimes be resolved at compile time (eg when static values are involved, cf <code>&lt;type_traits&gt;</code>). Adapting the answers below to other types of static branching (eg, multiple branches or multi-criteria branches) should be straightforward. Note that compile-time branching using template-meta programming is not the topic here.</p>
  
  <hr>
  
  <p>In a typical code like this</p>
  
  <pre><code>#include &lt;type_traits&gt;
  
  template &lt;class T&gt;
  T numeric_procedure( const T&amp; x )
  {
      if ( std::is_integral&lt;T&gt;::value )
      {
          // Integral types
      }
      else
      {
          // Floating point numeric types
      }
  }
  </code></pre>
  
  <p>will the compiler optimize the if/else statement out when I define specific template types later on in my code?</p>
  
  <p>A simple alternative would be to write something like this:</p>
  
  <pre><code>#include &lt;type_traits&gt;
  
  template &lt;class T&gt;
  inline T numeric_procedure( const T&amp; x )
  {
      return numeric_procedure_impl( x, std::is_integral&lt;T&gt;() );
  }
  
  // ------------------------------------------------------------------------
  
  template &lt;class T&gt;
  T numeric_procedure_impl( const T&amp; x, std::true_type const )
  {
      // Integral types
  }
  
  template &lt;class T&gt;
  T numeric_procedure_impl( const T&amp; x, std::false_type const )
  {
      // Floating point numeric types
  }
  </code></pre>
  
  <p>Is there a difference in terms of performance between these solutions? Is there any non-subjective grounds for saying that one is better than the other? Are there other (possibly better) solutions to deal with compile-time branching?</p>