title: Why does std::forward discard constexpr-ness?
body: <p>Being not declared <code>constexpr</code>, <code>std::forward</code> will discard constexpr-ness for any function it forwards arguments to. <strong>Why is <code>std::forward</code> not declared <code>constexpr</code> itself so it can preserve constexpr-ness?</strong></p>
  
  <p>Example: (tested with g++ snapshot-2011-02-19)</p>
  
  <pre><code>#include &lt;utility&gt;
  
  template &lt;typename T&gt; constexpr int f(T x) { return -13;}
  template &lt;typename T&gt; constexpr int g(T&amp;&amp; x) { return f(std::forward&lt;T&gt;(x));}
  
  int main() {
    constexpr int j = f(3.5f);
    // next line does not compile: 
    // error: ‘constexpr int g(T&amp;&amp;) [with T = float]’ is not a constexpr function
    constexpr int j2 = g(3.5f);
  }
  </code></pre>
  
  <p>Note: technically, it would be easy to make <code>std::forward</code> constexpr, e.g., like so (note that in g <code>std::forward</code> has been replaced by <code>fix::forward</code>):</p>
  
  <pre><code>#include &lt;utility&gt;
  
  namespace fix {
    /// constexpr variant of forward, adapted from &lt;utility&gt;:
    template&lt;typename Tp&gt;
    inline constexpr Tp&amp;&amp;
    forward(typename std::remove_reference&lt;Tp&gt;::type&amp; t) 
    { return static_cast&lt;Tp&amp;&amp;&gt;(t); }
  
    template&lt;typename Tp&gt;
    inline constexpr Tp&amp;&amp;
    forward(typename std::remove_reference&lt;Tp&gt;::type&amp;&amp; t) 
    {
      static_assert(!std::is_lvalue_reference&lt;Tp&gt;::value, "template argument"
            " substituting Tp is an lvalue reference type");
      return static_cast&lt;Tp&amp;&amp;&gt;(t);
    }
  } // namespace fix
  
  template &lt;typename T&gt; constexpr int f(T x) { return -13;}
  template &lt;typename T&gt; constexpr int g(T&amp;&amp; x) { return f(fix::forward&lt;T&gt;(x));}
  
  int main() {
    constexpr int j = f(3.5f);
    // now compiles fine:
    constexpr int j2 = g(3.5f);
  }
  </code></pre>
  
  <p>My question is: why is <code>std::forward</code> not defined like <code>fix::forward</code> ?</p>
  
  <p>Note2: this question is somewhat related to my other <a href="https://stackoverflow.com/questions/5087364/how-to-query-a-constexpr-stdtuple-at-compile-time">question about constexpr std::tuple</a> as <code>std::forward</code> not being <code>constexpr</code> is the technical reason why <code>std::tuple</code> cannot be created by calling its cstr with rvalues, but this question here obviously is (much) more general.</p>