Question

On implementation of operator- for is_densevector classes, I want:

g = -v; call the first version of operator (a clone of v will be negative), and:

g = -std::move(v);
g = -(v + v);
g = -std::vector<double>({1,2,3});

call the second version of operator (vector itself will be negative -- for performance).

The trick is the !std::is_reference<C>::value but I am not sure if this is correct. It seems that it is working.

//! Return the negative of vector \p v.
template<typename C>
typename std::enable_if<is_densevector<C>::value, C>::type
operator-(const C &v) { return ....; }

//! Return the negative of vector \p v.
template<typename C>
typename std::enable_if<!std::is_reference<C>::value && is_densevector<C>::value, C>::type
&&operator-(C &&v) { ....; return std::move(v); }
Was it helpful?

Solution

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); }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top