title: std::remove_const with const references
body: <p>Why does <code>std::remove_const</code> not convert <code>const T&amp;</code> to <code>T&amp;</code>? This admittedly rather contrived example demonstrates my question:</p>
  
  <pre><code>#include &lt;type_traits&gt;
  
  int main()
  {
      int a = 42;
      std::remove_const&lt;const int&amp;&gt;::type b(a);
  
      // This assertion fails
      static_assert(
          !std::is_same&lt;decltype(b), const int&amp;&gt;::value,
          "Why did remove_const not remove const?"
      );
  
      return 0;
  }
  </code></pre>
  
  <p>The above case is trivially easy to fix, so for context, imagine the following:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  template &lt;typename T&gt;
  struct Selector
  {
      constexpr static const char* value = "default";
  };
  
  template &lt;typename T&gt;
  struct Selector&lt;T&amp;&gt;
  {
      constexpr static const char* value = "reference";
  };
  
  template &lt;typename T&gt;
  struct Selector&lt;const T&amp;&gt;
  {
      constexpr static const char* value = "constref";
  };
  
  int main()
  {
      std::cout
          &lt;&lt; Selector&lt;typename std::remove_const&lt;const int&amp;&gt;::type&gt;::value
          &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>
  
  <p>In the above example, I'd expect <code>reference</code> to be shown, rather than <code>constref</code>.</p>