As far as I'm aware nullptr
is a part of the core language.
Quoting C++11: (18.2/9)
nullptr_t
is defined as follows:
namespace std { typedef decltype(nullptr) nullptr_t; }
and is defined in the header <cstddef>
.
Because it can. A central aim in the C++ standardization process is to alter the core language as little as possible when adding to the language.
nullptr
usurps the use of 0
to mean both a null pointer and, er, zero. Using 0
for both caused problems for obvious reasons, does f(0)
call f(int)
or f(int*)
? So a brand new literal was added to the core language: nullptr
. Its type is simply decltype(nullptr)
so nullptr_t
was added as a short cut:
namespace std {
using nullptr_t = decltype(nullptr);
}
std
typedefs like e.g. std::stize_t
are provided through headers, so what?
Commented
Aug 23, 2019 at 14:59
nullptr
is a literal like 5
, 'a'
or "hello"
. While I can't imagine what it is, I would bet there is a good technical reason why a null pointer literal is better than having a nullptr
-like object in std
. Edit : For one thing, being a literal it's a prvalue so you can't take it's address. It would seem strange to me to be able to take nullptr
's address. It would be like getting true
's address.
Commented
Aug 23, 2019 at 14:59
The proposal that introduced nullptr
, N2431, indicates in section 1.1 that it was desirable to not force users to include a header in order to use nullptr
.
It also remarks, "We do not expect to see much direct use of nullptr_t
in real programs". Thus, it was considered preferable to add nullptr_t
to the library rather than create a new keyword only to be used for this obscure purpose. In addition, if you don't want to include the header, you can always just write decltype(nullptr)
yourself.
From cppreference.com:
std::nullptr_t is the type of the null pointer literal, nullptr. It is a distinct type that is not itself a pointer type or a pointer to member type.
If two or more overloads accept different pointer types, an overload for std::nullptr_t is necessary to accept a null pointer argument.
You can then solve overloaded function call ambiguity with std::nullptr_t
.
For example:
void Foo(int* ptr) {}
void Foo(double* ptr) {}
void Foo(std::nullptr_t ptr) {} // This overload is called if Foo(nullptr) is invoked
Read more about std::nullptr_t
here: https://en.cppreference.com/w/cpp/types/nullptr_t
nullptr_t
if you are willing to live withdecltype(nullptr)
.nullptr_t
isn't a core concept, it's a helper.nullptr_t
sometimes: "If two or more overloads accept different pointer types, an overload forstd::nullptr_t
is necessary to accept a null pointer argument." (cppreference for std::nullptr_t).nullptr_t
if you are willing to live withdecltype(nullptr)
. You can usedecltype(nullptr)
instead ofnullptr_t
.nullptr_t
is just a convenient alias fordecltype(nullptr);
. You should usenullptr_t
, my comment is meant to indicate whynullptr_t
might not be part of the core language.nullptr
part of the language, it is much easier to ensure that it works as it should because you can easily have specific rules.