For the same reason as
if( p ) { ... }
compiles: any value of basic type converts implicitly to boolean, with 0
converting to false
and any other value to true
.
Originally basic type values had to convert to bool
for C compatibility. C didn't originally have a bool
type, but any numerical expression could be used as a boolean (with the 0 == false
convention). And now we're caught in the backward compatibility tangle. nullptr
has to support idiomatic constructs such as if(p)
, especially for the cases where old code's literal 0
or NULL
is replaced with nullptr
. E.g. code like if(p)
can result from a macro expansion, or in template code.
Addendum: the technical how of why nullptr
doesn't convert to e.g. int
.
Since nullptr
converts implicitly to bool
, and bool
(unfortunately) converts implicitly to int
, one could expect that nullptr
should also convert to int
. But the point of nullptr
is that it should behave as a pointer value. And while pointers do convert implicitly to bool
, they do not convert implicitly to numerical types.
Arranging such a restriction for a user-defined type is however not entirely straightforward. An operator bool
conversion will be invoked for conversion to int
, if it's present. One C++11 solution to enfore the restriction, is to make the conversion operator a template, restricted by a std::enable_if
, as follows:
#include <type_traits> // std::enable_if, std::is_same
struct S
{
template< class Type >
operator Type* () const { return 0; }
template<
class Bool_type,
class Enabled = typename std::enable_if<
std::is_same<Bool_type, bool>::value, void
>::type
>
operator Bool_type () const { return false; }
};
auto main() -> int
{
bool const b = S(); // OK.
double const* const p = S(); // OK.
int const i = S(); // !Doesn't compile.
}