Why "bool c = nullptr ;" compiles (C++11)?

c++, c++11, null-pointer, pointers

Solution

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

Problem

I don't understand why following code compiles ? ``` int main() { //int a = nullptr; // Doesn't Compile //char b = nullptr; // Doesn't Compile bool c = nullptr; // Compiles return 0; } ``` whereas the commented section doesn't. I've already gone through this and this. Both `bool` and `nullptr` are keywords, so what's unique about the other data types?

Original source

Related problems