nullptr - Pointer Literal
nullptr is a pointer literal introduced in C++11, used to represent null pointers. It addresses the shortcomings of traditional null pointer representations (such as NULL and 0) in terms of type safety and overload resolution.
Why was it introduced?
- Resolve ambiguity issues with
NULLmacro and integer0in overload resolution - Provide type-safe null pointer representation
- Clearly distinguish between pointer and integer types
- Support type deduction in template programming
What's the difference between nullptr and NULL?
nullptris a keyword introduced in C++11, with typestd::nullptr_tNULLis a preprocessor macro, typically defined as integer0or(void*)0nullptris more precise in overload resolution and won't be confused with integer types
I. Basic Usage and Scenarios
Replacing NULL and 0
Used for pointer variable initialization and assignment, replacing traditional
NULLand0
int* ptr1 = nullptr; // Recommended usage
int* ptr2 = NULL; // Traditional usage
int* ptr3 = 0; // Not recommended
// Check if pointer is null
if (ptr1 == nullptr) {
// Handle null pointer case
}
Resolving Overload Ambiguity
Explicitly passing null pointers in function calls,
nullptrcan avoid overload ambiguity issues and prevent confusion with integer types
void func(int* ptr) {
if (ptr != nullptr) {
*ptr = 42;
}
}
void func(int value) {
// Handle integer parameter
}
int main() {
func(nullptr); // Explicitly call pointer version
func(0); // May call integer version, causing ambiguity
func(NULL); // May call integer version, causing ambiguity
}
For example, in the code above, calling func(NULL) will report an overload ambiguity error
main.cpp: In function 'int main()':
main.cpp:16:9: error: call of overloaded 'func(NULL)' is ambiguous
16 | func(NULL); // May call integer version, causing ambiguity
| ~~~~^~~~~~
Ensuring Type Safety in Template Programming
In template functions and classes,
nullptrprovides better type deduction and safety
// https://en.cppreference.com/w/cpp/language/nullptr.html
template<class T>
constexpr T clone(const T& t) {
return t;
}
void g(int*) {
std::cout << "Function g called\n";
}
int main() {
g(nullptr); // ok
g(NULL); // ok
g(0); // ok
g(clone(nullptr)); // ok
g(clone(NULL)); // ERROR: NULL might be deduced to non-"pointer" type
g(clone(0)); // ERROR: 0 will be deduced to non-"pointer" type
}
When using function templates, NULL and 0 are usually deduced to non-"pointer" types, while nullptr can avoid this problem
main.cpp:19:12: error: invalid conversion from 'int' to 'int*' [-fpermissive]
19 | g(clone(0)); // ERROR: 0 will be deduced to non-"pointer" type
| ~~~~~^~~
| |
| int
Smart Pointers and Containers
Used with modern C++ features (such as smart pointers, STL containers)
#include <memory>
#include <vector>
int main() {
std::shared_ptr<int> sp1 = nullptr;
std::unique_ptr<int> up1 = nullptr;
std::vector<int*> vec;
vec.push_back(nullptr);
// Check if smart pointer is null
if (sp1 == nullptr) {
sp1 = std::make_shared<int>(42);
}
}
II. Important Notes
Type Deduction and std::nullptr_t
The type of nullptr is std::nullptr_t, which is a special type that can be implicitly converted to any pointer type:
#include <cstddef> // Contains definition of std::nullptr_t
void func(int*) {}
void func(double*) {}
void func(std::nullptr_t) {}
int main() {
auto ptr = nullptr; // ptr's type is std::nullptr_t
func(nullptr); // Call std::nullptr_t version
func(ptr); // Call std::nullptr_t version
int* intPtr = nullptr;
func(intPtr); // Call int* version
}
Implicit Conversion to Boolean Type
nullptr can be implicitly converted to bool type, which is very convenient in conditional checks:
int* ptr = nullptr;
if (ptr) { // Equivalent to if (ptr != nullptr)
// Pointer is not null
} else {
// Pointer is null
}
bool isEmpty = (ptr == nullptr); // true
III. Practice Code
Practice Code Topics
- 0 - nullptr Basic Usage
- 1 - nullptr Function Overloading
- 2 - nullptr Advantages in Template Programming
Auto-Checker Command
d2x checker nullptr