Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I'm trying to design a bool wrapper struct applying the safe bool idiom.
The classic implementation to solve this is pretty trivial: the skeleton could be something like this:

struct Bool final
{
  Bool() = default;

  Bool(bool value)
    : _value{value}
  {}

  explicit operator bool() const {
    return _value;
  }

private:
  bool _value{false};
};

The part I'm trying to improve is how Bool is constructed.
For example I want to avoid implicit narrowing by design:

Bool b1(45); // yields warnings, but it compiles
Bool b2{3};  // not ok by standard

I tried to hurt myself using templates, but without success.

How could I make it work?

share|improve this question
3  
You may also want to look at some prior art regarding safe bool. For example, this page goes through the process of making a safe bool and explaining some of the pitfalls which one can run into along the way (for example, an operator bool comes with some unintended side effects that other cast operators can avoid) – Cort Ammon 15 hours ago
    
Thank you! I'll definitely take a look at it! – steazzalini 9 hours ago
up vote 33 down vote accepted

You can achieve this by explicitly deleting all other constructors.

struct Bool final
{
    template<class T>
    Bool(T) = delete;

    Bool(bool value) : _value{value}
    {}
};
share|improve this answer
1  
where was the declaration of _value? did you omit that for brevity? – cat 15 hours ago
    
@cat I omitted everything but the constructors. – François Andrieux 15 hours ago

Add, and explicitly delete a template constructor:

template <typename T>
Bool(T) = delete;

It matches anything other than actual bool better than other constructors, and will thus prevent implicit conversion.

share|improve this answer
4  
"anything other than actual bool" -- and Bool: this doesn't, and probably shouldn't, disable the compiler-generated copy and move constructors. – hvd 17 hours ago

If you just need:
A variable that is only "true" or "false" and cannot be implicitly converted to int/char/pointer then I would look at using an enum class:

enum class Bool {
    False,
    True,
};
share|improve this answer

I'm trying to design a bool wrapper struct applying the safe bool idiom.

Don't.

The safe bool idiom is only relevant in C++03 and earlier - where if you express that your type is "truthy" by doing something like:

struct A {
    operator bool() const;
};

you'd run into all sorts of issues like:

A{} + 4;    // ok?!
A{} < 0;    // ok?!
A{} == B{}; // ok if B also has operator bool??!

So the safe bool idiom was a solution to this accidental implicit conversion problem, using function pointers (of course, function pointers!).

In C++11, we have a way better solution:

struct A {
    explicit operator bool() const;
};

which does exactly what we want. In fact, it was literally designed to solve this problem. And while the safe bool idiom is fairly complicated scaffolding, explicit operator bool is super straightforward to use and just does the Right Thing. You don't need a wrapper for it - it's actually harder to use your wrapper than to write the explicit operator bool directly.

Moreover, your wrapper imposes on the user (a) non-derivability because you made Bool final and (b) an extra bool member, that you have to keep in sync, so it introduces rather than solves problems. Consider how much more work it would be for you to implement:

template <class T>
struct my_unique_ptr : Bool { ... };

vs

template <class T>
struct my_unique_ptr {
    T* ptr;

    explicit operator bool() const { return ptr; }
};
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.