使用移动语义和完美转发来实现“懒惰”#39;运营商+

时间:2014-10-27 00:28:22

标签: c++ lazy-evaluation move-semantics perfect-forwarding

我正在尝试写一个

friend T operator+( lhs, rhs){
};

现在,我想尽可能避免建造临时工。

例如:

  1. 如果lhsrhs都是const T&operator+应该从temp创建lhs副本构建,那么{{1}最后到temp += rhs;
  2. 如果return std::move(temp)lhs,那么我想直接将T&&加到rhs,然后加lhs += rhs;。这种情况避免了return std::move(lhs)中的复制构造,因为在表达式之外不需要输出(A+B)+C。请注意,我们可能必须(A+B)为案例1和案例2都提供公共代码。
  3. 同样,对于其他两种情况,temp(std::move(lhs))rhslhs都是rhs
  4. 通过编写四个重载,我设法做到了这一点。现在,我已经读过可以利用模板和T&&来减少重载次数,甚至可以只在一个模板函数中编写它。我无法理解如何。

    似乎我需要

    forward

    但我为内容所尝试的内容并不奏效。

    我可能需要处理另外一个问题。如果不是template<typename R, typename S, typename T> R operator+(S&& lhs, T&& rhs){ // ... }; 我们需要operator+operator-方法的主体,它在所有情况下都不一定相似。在operator/中,如果A/BA,我们可以T&&。但如果A /= BB,那么我们可能需要执行T&&。所以,我想我还需要一种方法来了解在模板中输入了哪种情况。

    注意:我的乘法 IS 可交换(矩阵中的分量乘法)。

    您能否提供一些有关如何解决此问题的意见和建议?

    请注意自己和下一位读者link了解有关使用表达式模板的一些内容。

1 个答案:

答案 0 :(得分:2)

编写名为sum的函数。 sum有3个重载:lhs&&, rhs const&lhs const&, rhs&&, ... - ...很重要,因为它使得它成为最差的匹配,消除了歧义。最后const& lhs, const& rhs

然后template<lhs, rhs> auto operator+(lhs&&,rhs&&)->decltype完美转发到sum

一旦你开始工作,我们就可以继续前进。我们可以为每个操作符重新实现它,或者提升一个抽象级别。

你有一个变异的二元op(+=等)和一个反对称变换(对于大多数是noop,对于除法是反向的 - 对于除法的二进制op是*= btw)。将这些传递给像sum这样的重载调度程序。

对这两者使用函数对象,并且重写sum函数以使increase_mat{}noop{}变得容易。