Inv*_*rse 19 c++ operator-overloading rvalue-reference c++11
我正在添加新的运算符重载以利用c ++ 0x rvalue引用,我觉得我正在生成大量冗余代码.
我有一个类,tree
它在双值上包含一个代数运算树.这是一个示例用例:
tree x = 1.23;
tree y = 8.19;
tree z = (x + y)/67.31 - 3.15*y;
...
std::cout << z; // prints "(1.23 + 8.19)/67.31 - 3.15*8.19"
Run Code Online (Sandbox Code Playgroud)
对于每个二元运算(如加号),每一方可以是左值tree
,右值tree
或double
.这导致每个二进制操作有8个重载:
// core rvalue overloads for plus:
tree operator +(const tree& a, const tree& b);
tree operator +(const tree& a, tree&& b);
tree operator +(tree&& a, const tree& b);
tree operator +(tree&& a, tree&& b);
// cast and forward cases:
tree operator +(const tree& a, double b) { return a + tree(b); }
tree operator +(double a, const tree& b) { return tree(a) + b; }
tree operator +(tree&& a, double b) { return std::move(a) + tree(b); }
tree operator +(double a, tree&& b) { return tree(a) + std::move(b); }
// 8 more overloads for minus
// 8 more overloads for multiply
// 8 more overloads for divide
// etc
Run Code Online (Sandbox Code Playgroud)
这也必须以每种二进制操作(减号,乘法,除法等)的方式重复.
正如您所看到的,实际上我只需要编写4个函数; 其他4个可以转发并转发到核心案例.
您对减少此代码的大小有什么建议吗?
PS:这个类实际上比一个双打树更复杂.减少副本确实可以显着提高项目的性能.因此,即使使用额外的代码,rvalue重载对我来说也是值得的.我有一个怀疑,有可能是一种方式模板走了"的演员和转发"上面的情况,但我似乎无法想象的事情.
只是一个快速的回答:如果有问题的类是可移动的,那么移动非常便宜,如果可以,你总是会从所有参数中移出,然后按值传递参数可能是一个选项:
tree operator +(tree a, tree b);
Run Code Online (Sandbox Code Playgroud)
如果树是可移动的并且rvalue ref作为实际参数传递,那么函数的参数将在可能的情况下使用树的移动构造函数初始化,否则复制构造函数.然后,函数可以以适当的方式对其参数执行任何操作(例如,移动其内部).
当传递rvalue引用参数与lot-of-overloads版本相比时,它会产生额外的移动,但我认为它通常更好.
此外,IMO,tree &&
参数应该可以通过临时副本接受左值,但这不是任何编译器目前所做的,所以它不是很有用.
归档时间: |
|
查看次数: |
1469 次 |
最近记录: |