What exactly is nullptr?

When you have a function that can receive pointers to more than one type, calling it with NULL is ambiguous. The way this is worked around now is very hacky by accepting an int and assuming it's NULL.

template <class T>
class ptr {
    T* p_;
    public:
        ptr(T* p) : p_(p) {}

        template <class U>
        ptr(U* u) : p_(dynamic_cast<T*>(u)) { }

        // Without this ptr<T> p(NULL) would be ambiguous
        ptr(int null) : p_(NULL)  { assert(null == NULL); }
};

In C++11 you would be able to overload on nullptr_t so that ptr<T> p(42); would be a compile-time error rather than a run-time assert.

ptr(std::nullptr_t) : p_(nullptr)  {  }

How is it a keyword and an instance of a type?

This isn't surprising. Both true and false are keywords and as literals they have a type ( bool ). nullptr is a pointer literal of type std::nullptr_t, and it's a prvalue (you cannot take the address of it using &).

  • 4.10 about pointer conversion says that a prvalue of type std::nullptr_t is a null pointer constant, and that an integral null pointer constant can be converted to std::nullptr_t. The opposite direction is not allowed. This allows overloading a function for both pointers and integers, and passing nullptr to select the pointer version. Passing NULL or 0 would confusingly select the int version.

  • A cast of nullptr_t to an integral type needs a reinterpret_cast, and has the same semantics as a cast of (void*)0 to an integral type (mapping implementation defined). A reinterpret_cast cannot convert nullptr_t to any pointer type. Rely on the implicit conversion if possible or use static_cast.

  • The Standard requires that sizeof(nullptr_t) be sizeof(void*).


Why nullptr in C++11? What is it? Why is NULL not sufficient?

C++ expert Alex Allain says it perfectly here (my emphasis added in bold):

...imagine you have the following two function declarations:

void func(int n); 
void func(char *s);
 
func( NULL ); // guess which function gets called?

Although it looks like the second function will be called--you are, after all, passing in what seems to be a pointer--it's really the first function that will be called! The trouble is that because NULL is 0, and 0 is an integer, the first version of func will be called instead. This is the kind of thing that, yes, doesn't happen all the time, but when it does happen, is extremely frustrating and confusing. If you didn't know the details of what is going on, it might well look like a compiler bug. A language feature that looks like a compiler bug is, well, not something you want.

Enter nullptr. In C++11, nullptr is a new keyword that can (and should!) be used to represent NULL pointers; in other words, wherever you were writing NULL before, you should use nullptr instead. It's no more clear to you, the programmer, (everyone knows what NULL means), but it's more explicit to the compiler, which will no longer see 0s everywhere being used to have special meaning when used as a pointer.

Allain ends his article with:

Regardless of all this--the rule of thumb for C++11 is simply to start using nullptr whenever you would have otherwise used NULL in the past.

(My words):

Lastly, don't forget that nullptr is an object--a class. It can be used anywhere NULL was used before, but if you need its type for some reason, it's type can be extracted with decltype(nullptr), or directly described as std::nullptr_t, which is simply a typedef of decltype(nullptr), as shown here:

Defined in header <cstddef>:

See:

  1. https://en.cppreference.com/w/cpp/types/nullptr_t
  2. and https://en.cppreference.com/w/cpp/header/cstddef
namespace std
{
typedef decltype(nullptr) nullptr_t; // (since C++11)
// OR (same thing, but using the C++ keyword `using` instead of the C and C++ 
// keyword `typedef`):
using nullptr_t = decltype(nullptr); // (since C++11)
} // namespace std

References:

  1. Cprogramming.com: Better types in C++11 - nullptr, enum classes (strongly typed enumerations) and cstdint
  2. https://en.cppreference.com/w/cpp/language/decltype
  3. https://en.cppreference.com/w/cpp/types/nullptr_t
  4. https://en.cppreference.com/w/cpp/header/cstddef
  5. https://en.cppreference.com/w/cpp/keyword/using
  6. https://en.cppreference.com/w/cpp/keyword/typedef

From nullptr: A Type-safe and Clear-Cut Null Pointer:

The new C++09 nullptr keyword designates an rvalue constant that serves as a universal null pointer literal, replacing the buggy and weakly-typed literal 0 and the infamous NULL macro. nullptr thus puts an end to more than 30 years of embarrassment, ambiguity, and bugs. The following sections present the nullptr facility and show how it can remedy the ailments of NULL and 0.

Other references:

  • WikiBooks, with sample code.
  • Here at Stack Overflow: Do you use NULL or 0 (zero) for pointers in C++?
  • template
  • Google group: comp.lang.c++.moderated - compiler discussion