Я добавляю новые перегрузки операторов, чтобы использовать ссылки С++ 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"
Для каждой бинарной операции (например, плюс) каждая сторона может быть либо lvalue tree
, rvalue 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
который также должен повторяться для каждой бинарной операции (минус, умножить, делить и т.д.).
Как вы можете видеть, действительно есть только 4 функции, которые мне действительно нужно писать; другие 4 могут отбрасывать и пересылать основные случаи.
Есть ли у вас предложения по уменьшению размера этого кода?
PS: Класс на самом деле более сложный, чем просто дерево двойников. Сокращение копий значительно повышает производительность моего проекта. Таким образом, перегрузки rvalue мне подходят, даже с дополнительным кодом. У меня есть подозрение, что может быть способ отформатировать вышеприведенные случаи "бросить" и "вперед", но я ничего не могу придумать.