We now have C++11 with many new features. An interesting and confusing one (at least for me) is the new nullptr
.
Well, no need anymore for the nasty macro NULL
.
int* x = nullptr;
myclass* obj = nullptr;
Still, I am not getting how nullptr
works. For example, Wikipedia article says:
C++11 corrects this by introducing a new keyword to serve as a distinguished null pointer constant: nullptr. It is of type nullptr_t, which is implicitly convertible and comparable to any pointer type or pointer-to-member type. It is not implicitly convertible or comparable to integral types, except for bool.
How is it a keyword and an instance of a type?
Also, do you have another example (beside the Wikipedia one) where nullptr
is superior to good old 0
?
14 s
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 usedNULL
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:
- https://en.cppreference.com/w/cpp/types/nullptr_t
- 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:
- Cprogramming.com: Better types in C++11 – nullptr, enum classes (strongly typed enumerations) and cstdint
- https://en.cppreference.com/w/cpp/language/decltype
- https://en.cppreference.com/w/cpp/types/nullptr_t
- https://en.cppreference.com/w/cpp/header/cstddef
- https://en.cppreference.com/w/cpp/keyword/using
- https://en.cppreference.com/w/cpp/keyword/typedef