使用移动语义和完美转发来实现"懒惰"运算符+
Using move semantics and perfect forwarding to implement a 'lazy' operator+
我正在尝试编写一个
friend T operator+( lhs, rhs){
};
现在,我想尽可能避免建造临时的。
例如:
- 如果
lhs
和rhs
都const T&
则operator+
应该从lhs
创建一个temp
复制构造,然后temp += rhs;
它,最后return std::move(temp)
。 - 如果
lhs
是T&&
那么我想直接rhs
求和它,如lhs += rhs;
,然后return std::move(lhs)
.这种情况避免了(A+B)+C
中的复制构造,因为在表达式外部不需要(A+B)
的输出。请注意,我们可能必须执行temp(std::move(lhs))
才能为这两种情况 1 提供通用代码。和案例 2。
同样,对于 - 其他两种情况,当
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&&
的那个,那么我们可能需要做B.reciprocal() *= A
.所以,我想我还需要一种方法来知道在模板中输入了哪个案例。
注意:我的乘法是可交换的(矩阵中的分量乘法(。
您能否就如何处理这个问题提出一些意见和想法?
给自己和下一个读者的注意事项:指向有关使用表达式模板的一些阅读的链接。
编写一个名为 sum
的函数。 sum
有 3 个重载:lhs&&, rhs const&
和 lhs const&, rhs&&, ...
- ...
很重要,因为它使它成为最差的匹配,消除了歧义。 最后const& lhs, const& rhs
.
然后template<lhs, rhs> auto operator+(lhs&&,rhs&&)->decltype
完美的前锋到sum
.
一旦你开始工作,我们就可以继续前进。 我们可以为每个运算符重新实现它,也可以提升一个抽象级别。
你有一个变异的二进制运算(+=
等(和一个反对称变换(大多数是noop,除法是逆的 - 除法的二进制运算是*=
顺便说一句(。 将它们传递给像sum
一样超载的调度程序。
对这两个函数对象使用函数对象,重写sum
函数以采用increase_mat{}
和noop{}
应该很容易。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用C++实现懒惰排序算法
- 如何用懒惰的传播实现细分树
- 使用移动语义和完美转发来实现"懒惰"运算符+