c++ - 添加新的 c++0x 右值引用运算符重载时如何减少冗余代码

标签 c++ operator-overloading c++11 rvalue-reference

我正在添加新的运算符重载以利用 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"

对于每个二元运算(如加号),每一边都可以是左值 tree、右值 treedouble。这导致每个二元操作有 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

对于每个二元运算(减、乘、除等),也必须以某种方式重复。

如您所见,我实际上只需要编写 4 个函数;其他 4 个可以转换并转发到核心案例。

您对减小这段代码的大小有什么建议吗?

PS:这个类实际上比一个 double 树更复杂。减少拷贝确实显着提高了我的项目的性能。所以,右值重载对我来说是值得的,即使有额外的代码。我怀疑可能有办法模板化上面的“cast and forward”案例,但我似乎想不出任何东西。

最佳答案

只是一个较晚的答案:如果所讨论的类是可移动的,那么移动非常便宜,并且如果可以的话,您总是会从所有参数中移动,那么按值传递参数可能是一种选择:

tree operator +(tree      a, tree      b);

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

与很多重载版本相比,在传递右值引用参数时确实会产生额外的 Action ,但我认为它通常更好。

此外,IMO,tree && 参数可能应该通过临时拷贝接受左值,但这不是任何编译器目前所做的,所以它不是很有用。

关于c++ - 添加新的 c++0x 右值引用运算符重载时如何减少冗余代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2696156/

相关文章:

c++ - 正确,有效地读取文件

pointers - Fortran 指针赋值可以通过类型绑定(bind)的泛型过程重载吗?

c++ - 在 C++ 中重载位移运算符

c++ - qobject_cast<QVBoxLayout*>(layout()),是否合适?

c++ - 在字符串常量之前预期为 ‘,’ 或 ‘...’

c++ - 以多态类型作为函数参数的 std::function 的容器

c++ - WICConvertBitmapSource() 给出链接错误

c++ - 首先从目录中读取较新的文件 - C++

c++ - 对标准库分配器指针类型的要求

c++ - 调用cout时,如何在struct中输出常量文本?