Reputation: 180
I have a repeated pattern in my code
enum { OUTSIDE_BSPH = 0, INSIDE_BSPH = 1 };
bool bsph = true;
//...
bsph = false;
f(OUTSIDE_BSPH, arg1, arg2, arg3, arg4, arg5);
if (bsph) {
f(INSIDE_BSPH, arg1, arg2, arg3, arg4, arg5);
}
g(OUTSIDE_BSPH, arg6, arg7, arg8);
if (bsph) {
g(INSIDE_BSPH, arg6, arg7, arg8);
}
h(OUTSIDE_BSPH, arg3, arg4, arg5);
if (bsph) {
h(INSIDE_BSPH, arg3, arg4, arg5);
}
// ...
that I would like to simplify. Could it be transformed into something like
caller(bsph, f, arg1, arg2, arg3, arg4, arg5);
caller(bsph, g, arg6, arg7, arg8);
caller(bsph, h, arg3, arg4, arg5);
// ...
without using pointers?
Upvotes: 0
Views: 60
Reputation: 45664
There are many ways. You can use the preprocessor:
#define CALL(f, ...) do { \
f(OUTSIDE_BSPH, __VA_ARGS__); \
if (bsph) \
f(INSIDE_BSPH, __VA_ARGS__); \
} while(0)
CALL(f, arg1, arg2, arg3, arg4, arg5);
CALL(g, arg6, arg7, arg8);
CALL(h, arg3, arg4, arg5);
#undef CALL
Just keep the area where your macro is defined small, and there shouldn't be any problems.
Or you can use templates and lambdas:
template <class F>
void call(bool bsph, F f) {
f(OUTSIDE_BSPH);
if (bsph)
f(INSIDE_BSPH);
}
call(bsph, [&](int x){ f(x, arg1, arg2, arg3, arg4, arg5); });
call(bsph, [&](int x){ g(x, arg6, arg7, arg8); });
call(bsph, [&](int x){ h(x, arg3, arg4, arg5); });
If you allowed for at least C++14, I would have preferred using a generic lambda, which isn't too far from the simplicity of the first solution:
auto call = [&](auto f){
f(OUTSIDE_BSPH);
if (bsph)
f(INSIDE_BSPH);
};
call([&](int x){ f(x, arg1, arg2, arg3, arg4, arg5); });
call([&](int x){ g(x, arg6, arg7, arg8); });
call([&](int x){ h(x, arg3, arg4, arg5); });
Upvotes: 1