【问题标题】:rvalue reference template argument deduction on operators运算符的右值引用模板参数推导
【发布时间】:2014-01-20 01:22:00
【问题描述】:

关于为is_densevector 类实现operator-,我想要:

g = -v; 调用第一个版本的运算符(v 的克隆将是负数),并且:

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

调用运算符的第二个版本(向量本身将是负数——出于性能考虑)。

诀窍是!std::is_reference&lt;C&gt;::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); }

【问题讨论】:

  • ideone.com/4suqp4 像这样??不确定is_densevector 做了什么
  • 不完全是。黑盒化的is_densevector&lt;C&gt;::valueC=std::vector&lt;Integral&gt;C=std::array&lt;Integral,Size&gt; 等都适用。同样在您的示例中,您没有使用“魔术”C&amp;&amp;v 作为函数参数。
  • 你是什么意思我没有使用移动'魔法'作为函数参数?它在运算符的第二个声明中使用移动语义。我发布的签名与您拥有的签名之间的唯一区别是您的签名是模板化的。再次检查上面的链接,发现它使用了移动语义,因为分配的向量是临时的。给操作符添加打印语句,查看:ideone.com/4cOh1i

标签: c++ templates c++11 operator-overloading rvalue-reference


【解决方案1】:

你的做法是正确的。既然你忘了问一个真正的问题,我假设你想检查它为什么有效/是必要的?这是必要的,因为在第二种情况下,对于C&amp;&amp;,扣除将产生const T&amp;T&amp;。通过引用折叠,右值引用被删除。由于现在这与第一个重载有歧义,因此您需要通过检查 is_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); }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    相关资源
    最近更新 更多