title: How can I use C++11 parameter packs to distinguish between compile time constants and runtime vars?
body: <p>I am trying to make an optimal function that would accept compile-time constants and runtime constants, and do optimization at compile-time when the compiler knows the value. The problem is when I try to unpack the parameter pack it has to be moved into a runtime variable causing the compiler not to optimize in the same manner as if the constants was properly propagated. Unfortunately I'm not quite sure how to unpack to a single object while maintaining a mixture of compile-time and runtime variables in the same structure.</p>
  
  <p>I have two working test cases: one that does what it suppose to do (assembly-wise), but is not generic with regards to parameter packs. The other does have a parameter packs, but the compiler loses the compile-time constant through the unpacking.</p>
  
  <pre><code>// Example program
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;type_traits&gt;
  #include &lt;functional&gt;
  #include &lt;tuple&gt;
  
  struct ii{
      int value;
  };
  
  template&lt;int Val&gt;
  using tt = std::conditional_t&lt;Val==0, ii, std::integral_constant&lt;int, Val&gt; &gt;;
  
  
  template&lt;int... vals&gt;
  void foo( tt&lt;vals&gt;... inp)
  {
      const int arr[sizeof...(inp)]  = {inp.value...};
  
      std::cout &lt;&lt; "parameter " &lt;&lt; (16 / arr[0]) &lt;&lt; std::endl; //&lt;-incorrect asm
      std::cout &lt;&lt; "parameter " &lt;&lt; (16/ arr[1] ) &lt;&lt; std::endl; //expected asm
  }
  
  
  void check(ii i, std::integral_constant&lt;int, 4&gt; a)
  {
    std::cout &lt;&lt; "i = " &lt;&lt; ( 16 / i.value ) &lt;&lt; std::endl; //&lt;--expected asm
    std::cout &lt;&lt; "i = " &lt;&lt; (16 / a.value )  &lt;&lt; std::endl; //&lt;--this is OK in asm
  }
  
  
  int main()
  {
    std::integral_constant&lt;int, 4&gt; four;
    check(ii{1},four );
  
    foo&lt;four.value,0&gt;(four, ii{1});
  }
  </code></pre>
  
  <p>The expected results for "(16 / arr[0])" should be calculated at compile time, and it should be a constant 4. </p>
  
  <p>Thank you!</p>