我正在尝试写一个
friend T operator+( lhs, rhs){
};
现在,我想尽可能避免建造临时工。
例如:
lhs
和rhs
都是const T&
,operator+
应该从temp
创建lhs
副本构建,那么{{1}最后到temp += rhs;
。return std::move(temp)
为lhs
,那么我想直接将T&&
加到rhs
,然后加lhs += rhs;
。这种情况避免了return std::move(lhs)
中的复制构造,因为在表达式之外不需要输出(A+B)+C
。请注意,我们可能必须(A+B)
为案例1和案例2都提供公共代码。temp(std::move(lhs))
或rhs
和lhs
都是rhs
。通过编写四个重载,我设法做到了这一点。现在,我已经读过可以利用模板和T&&
来减少重载次数,甚至可以只在一个模板函数中编写它。我无法理解如何。
似乎我需要
forward
但我为内容所尝试的内容并不奏效。
我可能需要处理另外一个问题。如果不是template<typename R, typename S, typename T>
R operator+(S&& lhs, T&& rhs){
// ...
};
我们需要operator+
或operator-
方法的主体,它在所有情况下都不一定相似。在operator/
中,如果A/B
为A
,我们可以T&&
。但如果A /= B
是B
,那么我们可能需要执行T&&
。所以,我想我还需要一种方法来了解在模板中输入了哪种情况。
注意:我的乘法 IS 可交换(矩阵中的分量乘法)。
您能否提供一些有关如何解决此问题的意见和建议?
请注意自己和下一位读者:link了解有关使用表达式模板的一些内容。
答案 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{}
变得容易。