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
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.