Why does std::remove_const not convert const T& to T&? This admittedly rather contrived example demonstrates my question:
std::remove_const removes top level const-qualifications. In const T&, which is equivalent to T const&, the qualification is not top-level: in fact, it does not apply to the reference itself (that would be meaningless, because references are immutable by definition), but to the referenced type.
Table 52 in Paragraph 20.9.7.1 of the C++11 Standard specifies, regarding std::remove_const:
The member typedef type shall name the same type as
Texcept that any top-level const-qualifier has been removed. [ Example:remove_const<const volatile int>::typeevaluates tovolatile int, whereasremove_const<const int*>::typeevaluates toconst int*. — end example ]
In order to strip const away, you first have to apply std::remove_reference, then apply std::remove_const, and then (if desired) apply std::add_lvalue_reference (or whatever is appropriate in your case).
NOTE: As Xeo mentions in the comment, you may consider using an alias template such as Unqualified to perform the first two steps, i.e. strip away the reference, then strip away the const- (and volatile-) qualification.