patterncppMinor
Avoid duplicated += -= operator code
Viewed 0 times
duplicatedcodeoperatoravoid
Problem
In C++ (and C++11), classes defining a
What is the best way to avoid duplicated code here (and still achieve good performance)? I am sure there is a good way to do it with functors:
Here's what I've tried:
Note that this is a simple example; in reality the code in the
Also, I am not married to functors in the solution-- any suggestions or advice?
+ and += operators often define a - and -= operators that do nearly the same thing (except + is replaced with - in the function). What is the best way to avoid duplicated code here (and still achieve good performance)? I am sure there is a good way to do it with functors:
Here's what I've tried:
#include
#include
struct num {
int val;
const num & operator +=(const num & rhs) {
return op_equals >(rhs);
}
const num & operator -=(const num & rhs) {
return op_equals >(rhs);
}
template
const num & op_equals(const num & rhs) {
op operation;
val = operation(val, rhs.val);
return *this;
}
};
int main() {
num x{1};
num y{2};
x += y;
std::cout << x.val << std::endl;
return 0;
}Note that this is a simple example; in reality the code in the
+= and -= operators is more complex.Also, I am not married to functors in the solution-- any suggestions or advice?
Solution
I actually quite like this pattern and use it relatively often. I'm not sure if there is something better than functors for this - if there is, I'm not really aware of it. That being said, with C++11, I'd write this in a slightly different way:
Note the rvalue reference (which is actually a "universal reference", so can bind to either an lvalue or rvalue reference), and the movement of
struct num {
int val;
const num& operator +=(const num & rhs) {
return op_equals(rhs, std::plus());
}
const num& operator -=(const num & rhs) {
return op_equals(rhs, std::minus());
}
template
const num & op_equals(const num & rhs, op&& o) {
val = o(val, rhs.val);
return *this;
}
};Note the rvalue reference (which is actually a "universal reference", so can bind to either an lvalue or rvalue reference), and the movement of
op to a parameter - I don't really like having to specify it as a template parameter which then gets instantiated and called in the function. I think this way is slightly cleaner.Code Snippets
struct num {
int val;
const num& operator +=(const num & rhs) {
return op_equals(rhs, std::plus<int>());
}
const num& operator -=(const num & rhs) {
return op_equals(rhs, std::minus<int>());
}
template <typename op>
const num & op_equals(const num & rhs, op&& o) {
val = o(val, rhs.val);
return *this;
}
};Context
StackExchange Code Review Q#13140, answer score: 3
Revisions (0)
No revisions yet.