Have you ever seen a function call like this?

process(true, false);

We are processing something: this should be clear from the context. But what do these parameters mean? What is true and what is false ? From the function call we will never figure it out. The code surely isn’t self explanatory.

We will have to stop, and take a look at the declaration, and it does give us a hint:

void process(bool withValidation, bool withNewEngine);

Apparently, the author of the function uses the two bool s as toggles. The implementation will probably be something like this:

void process(bool withValidation, bool withNewEngine) { if (withValidation) // toggle #1 used validate(); do_something_toggle_independent_1(); if (withNewEngine) // toggle #2 used do_something_new(); else do_something_old(); do_something_toggle_independent_2(); }

From the author’s point of view, or the function’s definition point of view, there is no problem with readability, because each toggle has a name assigned to it. The problem occurs only on the side of the caller. The problem is not only with not being able to initially identify the toggles. If you already know the toggles, you can easily confuse their order. In fact, my initial example should have read:

process(false, true);

But I confused the order of the arguments. Did you notice that?

Once this bug hits the programmer, and she has determined the cause, she will probably put a comment in the function call to make the intention clear:

process(/*withValidation=*/ false, /*withNewEngine=*/ true);

And this almost looks as a missing language feature: named function parameters. Theoretically, this could look something like this:

// NOT IN C++: process(withValidation: false, withNewEngine: true);

But even if such feature were added into C++ it is not likely that it would inter-operate with forwarding functions. The following use cases would remain unaddressed:

std::function<void(bool, bool)> callback = &process; callback(???, ???); // what names to use?

There is a potential here for an even more contrived bug, far more difficult to track down. Suppose function process is a virtual member function. And in some other class you overload it, and in the overload you take the toggles in the wrong order:

struct Base { virtual void process(bool withValidation, bool withNewEngine); }; struct Derived : Base { void process(bool withNewEngine, bool withValidation) override; };

The compiler will not detect the problem, because the semantics are only encoded in parameter names. And the types of the toggles are just two bool s.

And this is not the end of the bugs caused by using bool s in the interface. Because almost every built-in type converts to bool the following compiles fine, and does something else than expected:

std::vector<int> vec; process(vec.data(), vec.size());

This problem is more common when toggles are used in constructors. Suppose your class has two constructors:

class C { explicit C(bool withDefaults, bool withChecks); explicit C(int* array, size_t size); };

At some point you decide to remove the second constructor, and you might hope that compiler will tell you about all places that need to be fixed. But this will not happen. Due to implicit conversions to bool the first constructor will take over all the calls.

There is a reason why people often decide to use type bool to represent a toggle, though. It is the only built in type, available out of the box, designed for storing two states. The exact number required by a toggle.

Enumerations

In order to fix the above problems we have to provide a type different than bool that will:

encode different toggles as distinct types,

prevent any implicit conversions.

C++11 comes with strong enumerations, which address both of these issues. Also, we can use type bool as enumeration’s underlying type; this way we make sure we only encode two states, and that we use up only the size of one bool . First we define the toggles:

enum class WithValidation : bool { False, True }; enum class WithNewEngine : bool { False, True };

Now we can declare our function like this:

void process(WithValidation withValidation, WithNewEngine withNewEngine);

There is some redundancy in such declaration, but the usage is exactly what is needed:

process(WithValidation::False, WithNewEngine::True); // ok

And if I provide the toggles in the wrong order, I get a compiler error due to type mismatch:

process(WithNewEngine::True, WithValidation::False); // fails!

Each toggle is a different but regular type: they can be perfect-forwarded, and you cannot get their order wrong in function declarations or virtual member function overrides.

But using enumerations for the purpose of toggles comes with a certain cost. To some extent toggles are similar to values of type bool , but enumerations, being so strongly typed do not reflect this similarity. Implicit conversions from and to bool do not work (and this is desired), but also explicit conversions do not work, and this is a problem. If we go back to the body of the function process , it no longer compiles:

void process(WithValidation withValidation, WithNewEngine withNewEngine) { if (withValidation) // error: no contextual convert to bool validate(); // ... }

I have to use an explicit cast:

if (bool(withValidation)) // ok validate();

And if I need a logical expression of two toggles, it becomes even starnger:

if (bool(withNewEngine) || bool(withValidation)) validate();

Also, you cannot direct-initialize a scoped enumeration from a bool :

bool read_bool(); class X { WithNewEngine _withNewEngine; public: X() : _withNewEngine(read_bool()) // fails {} };

I need to do an explicit cast:

class X { WithNewEngine _withNewEngine; public: X() : _withNewEngine(WithNewEngine(read_bool())) // ok {} };

Maybe this could be considered as super-explicit safety feature, but this looks like a bit too much of explicitness. Strong enumerations are more explicit than explicit constructors/conversions.

tagged_bool

Thus, in order to prevent bugs caused by naked bool s and to avoid problems caused by strong enumerations, I had to come up with my own tool, which I called a tagged_bool . You can find the implementation here. It is quite short. You use it to create toggles like this:

using WithValidation = tagged_bool<class WithValidation_tag>; using WithNewEngine = tagged_bool<class WithNewEngine_tag>;

You need to forward-declare a distinct tag class, like WithValidation_tag . It does not need to be defined. It is used to render a unique instantiation of class template tagged_bool . Instances of this template offer explicit conversion to and from bool as well as from other instances of tagged_bool , because, as it is often the case in practice, the same bool value passed to the lower levels of the application becomes a different toggle with a different name. You use thus created toggles like this:

void process(WithValidation withValidation, WithNewEngine withNewEngine) { if (withNewEngine || withValidation) // ok validate(); // ... } process(WithValidation{true}, WithNewEngine{false}); // ok process(WithNewEngine{true}, WithValidation{false}); // fails

And that’s it. tagged_bool is part of Explicit library, which provides a number of tools for stating your intentions more explicitly in interfaces.