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>
First, I don't see why operator+ would modify the arguments at all (isn't this a typical immutable binary tree implementation), so there'd be no difference between r-value and l-value reference. But let's assume that the subtrees have a pointer up to the parent or something like that.
From the usage example you showed, it looks like there's an implicit conversion from double to tree. In that case, your "cast and forward" cases aren't needed, the compiler will find the user-defined conversion.
Don't the non-move overloads end up making a new instance to go into the new tree? If so, I think you can write three of your remaining four cases as forwarders.
tree operator +(tree&& a, tree&& b); // core case
tree operator +(tree a, tree b) { return std::move(a) + std::move(b); }
tree operator +(tree a, tree&& b) { return std::move(a) + std::move(b); }
tree operator +(tree&& a, tree b) { return std::move(a) + std::move(b); }
Of course, you can use a macro to help generate the three (or seven) forwarding versions of each operator.
EDIT: if those calls are ambiguous or resolve to recursion, how about:
tree add_core(tree&& a, tree&& b);
tree operator +(tree&& a, tree&& b) { return add_core(std::move(a), std::move(b)); }
tree operator +(tree a, tree b) { return add_core(std::move(a), std::move(b)); }
tree operator +(tree a, tree&& b) { return add_core(std::move(a), std::move(b)); }
tree operator +(tree&& a, tree b) { return add_core(std::move(a), std::move(b)); }
EDIT: repro of the operator failure to use implicit conversions:
#include
template
class tree;
template tree add(tree a, tree b)
{
std::cout << "added!" << std::endl << std::endl;
return tree();
}
template tree operator +(tree a, tree b) { return add(a, b); }
template
class tree
{
public:
tree() { }
tree(const tree& t) { std::cout << "copy!" << std::endl; }
tree(double val) { std::cout << "double" << std::endl; }
friend tree operator +(tree a, tree b);
};
int main()
{
tree(1.0) + 2.0;
return 0;
}
And version without templates where the implicit conversion works:
#include
class tree
{
public:
tree() { }
tree(const tree& t) { std::cout << "copy!" << std::endl; }
tree(double val) { std::cout << "double" << std::endl; }
friend tree operator +(tree a, tree b);
};
tree add(tree a, tree b)
{
std::cout << "added!" << std::endl << std::endl;
return tree();
}
tree operator +(tree a, tree b) { return add(a, b); }
int main()
{
tree(1.0) + 2.0;
return 0;
}