Vincent
Vincent

Reputation: 60421

C++ design : functions with boolean options

I have a question of "good design practices" in C++. I am writing a numerical library in C++11 and I use at lot of metaprogramming and template-based technique. But I have a very basic question :

Consider a function that can have a two very close behaviours excepted an option that can be activated by a boolean flag. I consider only a flag that can be set/unset by the developer and not a flag that can be set/unset at runtime. There are 3 possibilities of design :


1) Write two functions with the explicit option in their name :

myFunctionFlag1(...);
myFunctionFlag2(...); 

2) Use a template parameter :

template<bool Flag> myFunction(...);

3) Use a variable parameter :

myFunction(..., const bool flag);

In terms of good design practices which solution is acceptable/unacceptable ? If there is a best solution, which one is it and why ? If there is a worst solution, which one is it and why ?

EDIT : for the considered functions the runtime overhead could be considered as negligible, so this is not the most critical point.

EDIT 2 : I know that all the three work. But as my library will have users, it needs to have a reliable/good design.

Is the option 2 common (because it seems to me to be a good compromise) ?

Upvotes: 5

Views: 1272

Answers (5)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153945

Duplicating non-trivial code is the worst option. If the two functions do little more than dispatching to the actual interesting function it may be the right option. Of course, the two functions could dispatch to the templated version but they could give a better indication of what the difference is than true or false could do.

Another concern is how the functions are actually used: If they are themselves called from functions having the same configurations or configurations from which the choice of flags can be derived, using different names becomes rather annoying or even not maintainable: you'd end up with having to call functions conditionally:

(flag? &myFunctionFlag1: &myFunctionFlag2)(...);

The choice between the other two versions cones down to the question: does the check matter? If it does, the template is the only choice. If it doesn't you can choose either version and I'd bet that an anonymous poll would vote for the run-time version: the eyes of the majority of my colleagues glace over when I show them a trivial template.

Upvotes: 0

James McNellis
James McNellis

Reputation: 355167

None of the above. Boolean flags are terrible for code readability. If the flag-controlled functionality is sufficiently small that it makes sense to use a single function, then use a single function, but don't use bool as the type of the flag. Instead, use an enumeration with enumerators that have useful names:

enum class MyFunctionMode { EnableFoo, DisableFoo };

void myFunction(..., MyFunctionMode mode);

This pattern makes it easy to understand at the call site what options are being provided to the function. Multiple options may be combined using flags.

Upvotes: 11

Kirill Kobelev
Kirill Kobelev

Reputation: 10557

My recommendation would be to use the option 1.

Comments:

  1. The most simple and clear. It does not have run time overhead.
  2. I do not see enough justification (that might be still present if more details are given) for using this approach. It is more complex than option 1.
  3. This variant has run time overhead. It can be still used in a non time/CPU critical code. If your function is large (100+ lines), then this variant becomes more attractive,

My 2 cents.

Upvotes: 2

Edward Strange
Edward Strange

Reputation: 40877

You can do all three you know.

void fun_that_does_stuff();
void fun_that_does_something_else();

template < bool F >
void fun_that_does_stuff_or_something();
template < >
void fun_that_does_stuff_or_something<true>() { fun_that_does_stuff(); }

... blah blah.

Upvotes: 0

tomahh
tomahh

Reputation: 13661

Your first solution duplicates code, and that is something nobody wants to do.

In the third one is acceptable, but the if statement will be evaluate at run time, and implies a lose of time.

The template one seems to be appropriate. The if statement will be eather if (true) or if (false) at compile time, and the compiler will optimize it, as if they were no if statement.

Upvotes: 0

Related Questions