C++11, nullptr is a null pointer that can be used to assign a pointer (to any object type)
Generalized integral type (integral types) = char, short, int, long, long longnd and their unsigned counterparts, and bool, wchar_t, char16_t, and Char32_
1 Calling overloaded functions
0 in C + +, it is first treated as an int type. NULL in C + +, first as a generalized integer (integral types), as to the specific int,long or other, depending on the circumstances
The following three functions, because of the different types of formal parameters, constitute overloaded functions. If you are passing three different arguments to choose which function to invoke, the following problem occurs:
// three overloads of F void f (int); void F (bool); void f (void*); F (0); // calls F (int), not F (void*)f (NULL); // might not compile, but typically calls F (int). Never calls F (void*)// calls F (void*) overload
1) C + + regards 0 first as int, so calling f (0) calls F (int)
2) The case of NULL is more complicated, but C + + still regards it as the first generalized integer (integral tyoes). If NULL is defined as normal 0, then f (int) is called.
If NULL is defined as 0L, then long, int, long, bool, 0L-void*, these three cases are legal, at this time, the compiler will error
3) with nullptr, there will be no problem with overloaded function call Blur
-Nullptr is not a generalized integral type, nor is it a general-purpose pointer
-The actual type of nullptr is std::nullptr_t, which can be implicitly converted to all primitive pointer types, so it can be thought of as a pointer to all types
2 Code Clarity
Using nullptr instead of 0 or NULL can significantly improve the clarity of your code, as shown in the following example:
/**/ ); if 0 ) { /**/ ); if (Result = = nullptr) { ...}
Using 0 to compare with result, it is difficult to determine the return value type of FindRecord at first glance, because it may be a generalized integer or a pointer type
Instead of using nullptr, you can clearly know the return value of FindRecord, which must be a pointer type
3 Template functions
When a template is involved in a program, the benefits of using nullptr are more pronounced, as follows:
//Call these if the appropriate mutex is lockedintF1 (std::shared_ptr<widget>SPW); DoubleF2 (std::unique_ptr<widget>UPW);BOOLF3 (widget*PW);//calling code, wants to pass null pointersStd::mutex f1m, f2m, f3m;//mutexes for F1, F2, and F3usingMuxguard = std::lock_guard<std::mutex>;... {Muxguard g (f1m); //lock mutex for F1Auto result = F1 (0);//pass 0 as null PTR to F1}//Unlock Mutex... {Muxguard g (f2m); //lock Mutex for F2Auto result = F2 (NULL);//pass NULL as null PTR to F2}//Unlock Mutex... {Muxguard g (f3m); //lock Mutex for F3Auto result = F3 (nullptr);//pass nullptr as null PTR to F3}// unlock mutex
Lock mutex, call function--unlock mutex, this pattern is repeated three times in the program, in order to avoid this repetition, a template function can be used instead of
Template<typename Functype, TypeName Muxtype, TypeName ptrtype>Auto Lockandcall (functype func, Muxtype& Amp Mutex, Ptrtype ptr), Decltype (func (PTR)) // c++11{ Muxguard g (mutex); return func (PTR);}
Finally, the template function is called
0); // error! = Lockandcall (F2, f2m, NULL); // error! = Lockandcall (F3, f3m, nullptr); // Fine
When 0 is passed as an argument to the Lockandcall function, it is inferred by C + + as an int, which is obviously inconsistent with the desired std::shared_ptr<widget>-type parameter of F1, and therefore an error occurred
Similarly, NULL and F2 expected std::unique_ptr<widget>-type parameters also do not meet
Nullptr, when passed to F1 or F2 as PTR, is inferred as std::nullptr_t; when passed to F3 as PTR, std::nullptr_t is implicitly converted to widget*, ensuring consistent parameter types
Summary:
1) prefer nullptr to 0 and NULL
2) Avoid overloading on integral and pointer types
Resources
<effective Modern C++> Item 8
<c++ programming language> "integral types"
The nullptr of c++11