0

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?

2
  • How could you possibly avoid using pointers to functions (or references to functions, which in the generated code amounts to the same thing) in passing f to caller? Commented Nov 30, 2018 at 18:50
  • @DanielSchepler Macros. Or Lambdas. Commented Nov 30, 2018 at 19:33

1 Answer 1

1

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); });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.