According to cppreference, nullptr
is a keyword that:
denotes the pointer literal. It is a prvalue of type std::nullptr_t
.
There exist implicit conversions from nullptr to null pointer value of
any pointer type and any pointer to member type. Similar conversions
exist for any null pointer constant, which includes values of type
std::nullptr_t
as well as the macro NULL
.
So nullptr
is a value of a distinct type std::nullptr_t
, not int
. It implicitly converts to the null pointer value of any pointer type. This magic happens under the hood for you and you don't have to worry about its implementation. NULL
, however, is a macro and it is an implementation-defined null pointer constant. It's often defined like this:
#define NULL 0
i.e. an integer.
This is a subtle but important difference, which can avoid ambiguity.
For example:
int i = NULL; //OK
int i = nullptr; //error
int* p = NULL; //OK
int* p = nullptr; //OK
and when you have two function overloads like this:
void func(int x); //1)
void func(int* x); //2)
func(NULL)
calls 1) because NULL
is an integer.
func(nullptr)
calls 2) because nullptr
converts implicitly to a pointer of type int*
.
Also if you see a statement like this:
auto result = findRecord( /* arguments */ );
if (result == nullptr)
{
...
}
and you can't easily find out what findRecord
returns, you can be sure that result
must be a pointer type; nullptr
makes this more readable.
In a deduced context, things work a little differently. If you have a template function like this:
template<typename T>
void func(T *ptr)
{
...
}
and you try to call it with nullptr
:
func(nullptr);
you will get a compiler error because nullptr
is of type nullptr_t
. You would have to either explicitly cast nullptr
to a specific pointer type or provide an overload/specialization for func
with nullptr_t
.
- avoid ambiguity between function overloads
- enables you to do template specialization
- more secure, intuitive and expressive code, e.g.
if (ptr == nullptr)
instead of if (ptr == 0)
nullptr
is also used to represent null reference for managed handles in C++/CLI. – mmxnullptr_t
guaranteed to have only one member,nullptr
? So, if a function returnednullptr_t
, then the compiler already knows which value will be returned, regardless of the body of the function? – Aaron McDaidstd::nullptr_t
can be instantiated, but all instances will be identical tonullptr
because the type is defined astypedef decltype(nullptr) nullptr_t
. I believe the primary reason the type exists is so that functions can be overloaded specifically to catchnullptr
, if necessary. See here for an example. – Justin Time - Reinstate Monica