如何减少冗余代码时添加新的c ++ 0x右值引用运算符重载 [英] How to reduce redundant code when adding new c++0x rvalue reference operator overloads

查看:132
本文介绍了如何减少冗余代码时添加新的c ++ 0x右值引用运算符重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我添加了新的运算符重载,以利用c ++ 0x右值引用,我感觉我生成了大量的冗余代码。



我有一个类 tree ,它保存对double值的代数运算的树。下面是一个示例用例:

  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

like plus),每一边可以是左值,右值 double 。这会导致每个二进制操作的8个重载:

  //核心值重载的加号:
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);

//转换和转发情况:
树运算符+(const树& 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个更多的重载

// 8个更多的重载用于乘法

// 8个更多的重载用于除法

// etc

这也必须以一种方式重复每个二进制操作减,乘,除等)。



正如你所看到的,实际上只有4个函数我需要写;

>

PS:类实际上比仅仅一个双精度树更复杂。减少副本会显着提高我的项目的性能。所以,右值重载对我来说是值得的,即使有额外的代码。我有一个怀疑,可能有一种方法来模板离开上面的转发和转发的情况,但我似乎没有想到任何东西。

解决方案

只是一个很晚的答案:如果有问题的类是可移动的,移动是很便宜,你会永远从所有的参数,如果可以,值的参数可能是一个选项:

 树运算符+(树a,树b) 

如果树是可移动的,并且右值引用作为实际参数传递,将尽可能用树的移动构造函数初始化,否则复制构造函数。然后,函数可以以适当的方式使用它的参数来做任何想要的事情(例如,移动它们的内部)。



当传递



此外,IMO, tree&&&& ; 参数应该通过临时副本接受lvalues,但这不是任何编译器目前做的,所以它不是很有用。


I am adding new operator overloads to take advantage of c++0x rvalue references, and I feel like I'm producing a lot of redundant code.

I have a class, tree, that holds a tree of algebraic operations on double values. Here is an example use case:

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"

For each binary operation (like plus), each side can be either an lvalue tree, rvalue tree, or double. This results in 8 overloads for each binary operation:

// 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

which also has to be repeated in a way for each binary operation (minus, multiply, divide, etc).

As you can see, there are really only 4 functions I actually need to write; the other 4 can cast and forward to the core cases.

Do you have any suggestions for reducing the size of this code?

PS: The class is actually more complex than just a tree of doubles. Reducing copies does dramatically improve performance of my project. So, the rvalue overloads are worthwhile for me, even with the extra code. I have a suspicion that there might be a way to template away the "cast and forward" cases above, but I can't seem to think of anything.

解决方案

Just a quick late answer: If the class in question is moveable, the move is very cheap, and you would always move from all the arguments if you can, then passing the arguments by value might be an option:

tree operator +(tree      a, tree      b);

If tree is moveable and an rvalue ref is passed as the actual argument, then the arguments to the function will be initialized with tree's move constructor where possible, else the copy constructor. Then, the function can do whatever it wants with its arguments in the appropriate way (like, say, moving their internals around).

It does incur an extra move when passing an rvalue reference argument compared with the lots-of-overloads version, but I think it's generally better.

Also, IMO, tree && arguments should maybe accept lvalues via a temporary copy, but this is not what any compilers currently do, so it's not very useful.

这篇关于如何减少冗余代码时添加新的c ++ 0x右值引用运算符重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆