First of all, there's no particular reason for your variables to be named b05
and b06
, so let's use a
and b
, it looks less ugly.
Fundamentally you want to make a copy of your pair of values (two ints, 49
and 13
) and pass in a copy to the code which will change them.
The simplest solution is that you create 2 extra variables, assign your values to them:
int a0 = 49, b0 = 13;
and then every time you want to use them, you can copy the assignment:
a = a0; b = b0;
This will avoid duplicating constants (you only specify 49
and 13
once), however you still have to duplicate operators that copy variables.
Any further improvements will not let you avoid this copy, it still has to be done prior to every operation, but you can avoid some source code duplication with a few tricks:
(1) Using struct. That will let you encapsulate two values in one:
struct params {
int a;
int b;
}
params p0;
p0.a = 49;
p0.b = 13;
params p;
...
p = p0;
p.a += p.b; // p.a = p.a + p.b
cout << "(+=) compound assignment: " << p.b << endl;
...
Now you're repeating just one command p = p0
instead of two.
(2) Using value parameters:
void test1(int a, int b) {
a += b; cout << "(+=) compound assignment: " << a << endl;
}
void test2(int a, int b) {
a -= b; cout << "(-=) compound assignment: " << a << endl;
}
...
int main() {
int a = 49; int b = 13;
test1(a, b);
test2(a, b);
...
return 0;
}
While not explicitly assigning a and b, the copy still occurs every time: actual parameters a
and b
from main
are being copied into formal parameter variables of functions, coincidentally also named a
and b
.
(3) You can avoid duplicating code by using function references. Here is an example with array of anonymous functions for each operation:
typedef int OperationFn(int, int)
struct OperationInfo {
std::string label;
OperationFn op;
}
OperationInfo operations[9] = {
{ "+=", [](int a, int b) { return a += b } },
{ "-=", [](int a, int b) { return a -= b } },
{ "*=", [](int a, int b) { return a *= b } },
{ "/=", [](int a, int b) { return a /= b } },
{ "%=", [](int a, int b) { return a %= b } },
{ ">>=", [](int a, int b) { return a >>= b } },
{ "<<=", [](int a, int b) { return a <<= b } },
{ "&=", [](int a, int b) { return a &= b } },
{ "^=", [](int a, int b) { return a ^= b } },
}
int main() {
for (int i = 0; i < 9; i++) {
const OperationInfo& oi = operations[i];
cout << "(" << oi.label << ") compound assignment: ";
cout << oi.op(49, 13) << endl;
}
return 0;
}
The code mentions parameter substitution only once (oi.op(49, 13)
line), but it's in a loop, so it will effectively execute all 9 times. While code looks cleaner and more compact, there is no efficiency gain: you still copy both values prior to every test.
One optimization is possible though: you can use a shared const value for the second argument, because it's never modified:
const int b = 13;
and then don't pass b
around, just use b
.
Note: pardon my typos. I don't have compiler handy so I can't verify this code. It may have minor mistakes. Leave comments if you find them, I'll update my post.