C++ 运算符上的右值引用模板参数推断

C++ 运算符上的右值引用模板参数推断,c++,templates,c++11,operator-overloading,rvalue-reference,C++,Templates,C++11,Operator Overloading,Rvalue Reference,在为is\u densevector类实现操作符-时,我希望: g=-v调用operator的第一个版本(v的克隆将为负数),并且: g=-std::move(v); g=-(v+v); g=-std::vector({1,2,3}); 调用操作符的第二个版本(向量本身将是负数——为了性能) 诀窍是!std::is_reference::value,但我不确定这是否正确。它似乎在起作用 //! Return the negative of vector \p v. template<ty

在为
is\u densevector
类实现
操作符-
时,我希望:

g=-v调用operator的第一个版本(v的克隆将为负数),并且:

g=-std::move(v);
g=-(v+v);
g=-std::vector({1,2,3});
调用操作符的第二个版本(向量本身将是负数——为了性能)

诀窍是
!std::is_reference::value
,但我不确定这是否正确。它似乎在起作用

//! 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); }
/!返回向量的负数\p v。
模板
typename std::enable_if::type
运算符-(常量C&v){return….;}
//! 返回向量的负数\p v。
模板
typename std::enable_if::value&&is_densevector::value,C>::type
&&运算符-(C&&v){……;返回std::move(v);}

您所做的是正确的。既然你忘了问一个真正的问题,我想你应该检查一下为什么它有效/必要?这是必要的,因为在第二种情况下,对于
C&
,扣减将产生
const T&
T&
。通过引用折叠,删除右值引用。由于这现在与第一个重载不明确,因此需要通过检查
is\u reference
来消除歧义

请注意,这仅适用于完全推导的参数。另一个选项是以下选项,它依赖于简单的重载解析和仅推导向量的值类型,而不是整个向量类型的事实:

//! 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); }
/!返回向量的负数\p v。
模板
typename std::启用\u如果<
是_densevector::value,
向量
>::类型
运算符-(const std::vector&v){return….;}
//! 返回向量的负数\p v。
模板
typename std::启用\u如果<
是_densevector::value,
向量&&
>::类型
运算符-(std::vector&&v){……;返回std::move(v);}

像这样吗??不确定
是什么\u densevector
不确切。黑盒的
是_densevector::value
C=std::vector
C=std::array
等都是正确的。同样,在您的示例中,您没有使用'magic'
C&&v
作为函数参数。您不使用移动'magic'作为函数参数是什么意思?它在操作符的第二个声明中使用移动语义。我发布的签名与您拥有的签名之间的唯一区别是,您的签名是模板化的。再次检查上面的链接,并查看它是否使用移动语义,因为所分配的向量是临时的。向运算符添加打印语句,请参见:
//! 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); }