What you do is correct. Since you forgot to ask a real question, I assume you want to check why it works/is necessary? It is necessary because the deduction would yield const T&
or T&
for C&&
in the second case. Through reference collapsing the rvalue-reference is removed. Since this is now ambiguous with the first overload, you need to disambiguate it with the check for is_reference
.
Note that this is only required for a fully deduced parameter. Another option would be the following, which relies on simple overload resolution and the fact that only the value-type of the vector is deduced, not the whole vector-type:
//! Return the negative of vector \p v.
template<typename C>
typename std::enable_if<
is_densevector<std::vector<C>>::value,
std::vector<C>
>::type
operator-(const std::vector<C> &v) { return ....; }
//! Return the negative of vector \p v.
template<typename C>
typename std::enable_if<
is_densevector<std::vector<C>>::value,
std::vector<C>&&
>::type
operator-(std::vector<C> &&v) { ....; return std::move(v); }