What is the rationale for boost::none_t implementation?

Luc Touraille picture Luc Touraille · Jun 7, 2012 · Viewed 7.8k times · Source

Boost.Optional uses a dummy type to allow constructing uninitialized instances of boost::optional<T>. This type is called none_t, and an instance none is already defined in a header for convenience, allowing us to write code such as the following:

boost::optional<int> uninitialized(boost::none);

Looking at the definition of none_t, I noticed that it is in fact a typedef corresponding to a pointer-to-member to some dummy struct:

namespace boost {

namespace detail { struct none_helper{}; }

typedef int detail::none_helper::*none_t ;

none_t const none = (static_cast<none_t>(0)) ;

} // namespace boost

What are the advantages of using such a convoluted typedef over a simple empty struct like this?

namespace boost {

struct none_t {};

none_t const none;

} // namespace boost

Answer

Matthieu M. picture Matthieu M. · Jun 7, 2012

Ah, I had never thought to dig deeper.

One (more or less obvious) advantage to a regular struct, is that now none evaluates to false in boolean contexts.

One advantage over another "evaluates to false" is that pointer to member are prevented from harmful promotion to integral types.

So, I guess that it offers a safe and concise way of having a object that evaluates to false.

EDIT: One should recognize here (hum...) the structure of the Safe Bool Idiom.