visit
/!\: Originally published @ .
Note: This article is more or less the same thing which you can find , & in but in a bit organized & simplified way.
To distinguish between an integer 0(zero) i.e. NULL & actual null of type pointer.
1️⃣ Implicit conversion
char *str = NULL; // Implicit conversion from void * to char *
int i = NULL; // OK, but `i` is not pointer type
2️⃣ Function calling ambiguity
void func(int) {}
void func(int*){}
void func(bool){}
func(NULL); // Which one to call?
error: call to 'func' is ambiguous
func(NULL);
^~~~
note: candidate function void func(bool){}
^
note: candidate function void func(int*){}
^
note: candidate function void func(int){}
^
1 error generated.
compiler exit status 1
3️⃣ Constructor overload
struct String
{
String(uint32_t) { /* size of string */ }
String(const char*) { /* string */ }
};
String s1( NULL );
String s2( 5 );
struct nullptr_t
{
void operator&() const = delete; // Can't take address of nullptr
template<class T>
inline operator T*() const { return 0; }
template<class C, class T>
inline operator T C::*() const { return 0; }
};
nullptr_t nullptr;
struct C { void func(); };
int main(void)
{
int *ptr = nullptr; // OK
void (C::*method_ptr)() = nullptr; // OK
nullptr_t n1, n2;
n1 = n2;
//nullptr_t *null = &n1; // Address can't be taken.
}
void func(int) { /* ... */}
void func(int *) { /* ... */}
void func(bool) { /* ... */}
func(nullptr);
// int ptr_not_ok = reinterpret_cast<int>(nullptr); // Not OK
long ptr_ok = reinterpret_cast<long long>(nullptr); // OK
void func(int*) { /*...*/ }
void func(double*) { /*...*/ }
func(nullptr); // compilation error, ambiguous call!
// func(reinterpret_cast<int*>(nullptr)); // error: invalid cast from type 'std::nullptr_t' to type 'int*'
func(static_cast<int*>(nullptr)); // OK
int *ptr = nullptr;
if (ptr == 0); // OK
if (ptr <= nullptr); // OK
int a = 0;
if (a == nullptr); // error: invalid operands of types 'int' and 'std::nullptr_t' to binary 'operator=='
From : - …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.
const int a = 0;
if (a == nullptr); // OK
const int b = 5;
if (b == nullptr); // error: invalid operands of types 'const int' and 'std::nullptr_t' to binary 'operator=='
template <typename T>
void ptr_func(T *t) {}
ptr_func(nullptr); // Can not deduce T
template <typename T>
void val_func(T t) {}
val_func(nullptr); // deduces T = nullptr_t
val_func((int*)nullptr); // deduces T = int*, prefer static_cast though
From :
- In the context of a , a bool object may be initialized from a prvalue of type , including nullptr. The resulting value is false. However, this is not considered to be an implicit conversion.
bool b1 = nullptr; // Not OK
bool b2 {nullptr}; // OK
void func(bool){}
func(nullptr); // Not OK, need to do func(static_cast<bool>(nullptr));
typeid(nullptr); // OK
throw nullptr; // OK
char *ptr = expr ? nullptr : nullptr; // OK
// char *ptr1 = expr ? 0 : nullptr; // Not OK, types are not compatible
static_assert(sizeof(NULL) == sizeof(nullptr_t));
When was nullptr introduced?
Is nullptr a keyword or an instance of a type std::nullptr_t?
What are the advantages of using nullptr?
Is NULL in C++ equal to nullptr from C++11?
cout<<is_same_v<nullptr, NULL><<endl;
Can I convert nullptr to bool?
How is nullptr defined?
Previosuly published at //www.vishalchovatiya.com/what-exactly-nullptr-is-in-cpp/