A. Nullptr and nullptr_t
(A) nullptr_t is a data type , and an example of this nullptr type . Typically, you can create a new instance by nullptr_t another type.
(B) is defined as nullptr_t all types of data are equivalent, the behavior is exactly the same.
(C) STD :: nullptr_t type, not a pointer type , but may be implicitly converted into a pointer of any type (not to convert non-pointer type, nor strong turn).
(Iv) nullptr_t type of data is not available for arithmetic expressions. But it can be used for relational operation expression (only with the type of data or nullptr_t pointer type data comparison, if and only if the relational operators ==, <=,> = isochronous)
[Relationship] nullptr programming experiment with the nullptr_t
#include <the iostream> #include <Vector> #include <The iomanip> // for SetBase; #include <Boost / type_index.hpp> the using namespace STD; the using Boost :: :: typeindex type_id_with_cvr; // auxiliary class template for T type printing Template <typename T> void printType ( String S) { COUT << << S " = " . << type_id_with_cvr <T> () pretty_name () << endl; } // 4. test for nullptr not a pointer type template <typename T>void func_ptr (T * t) {} template <typename T> void func_value (T T) {} int main () { // 1. See nullptr type printType <the decltype (nullptr)> ( " nullptr type: " ); // STD :: nullptr_t COUT << " the sizeof (nullptr a) = " << the sizeof (nullptr a) << endl; // 2. nullptr a implicitly convertible to any pointers! void * = the vptr nullptr; char * CPTR = nullptr; // 3. Use relational operators compared with nullptr_t nullptr type variable // 3.1 nullptr support relational operators nullptr_t my_nullptr = nullptr; //By nullptr_t definitions (under vc must be initialized, but g ++ default has been initialized nullptr) new instance (nullptr == my_nullptr) (cout <<? " NewPtr == nullptr " << endl): (cout << " NewPtr! nullptr = " << endl); (nullptr ? <my_nullptr) (cout << " NewPtr <nullptr " << endl): (cout << " NewPtr <nullptr! " << endl); // 3.2 nullptr does not support arithmetic calculating // nullptr a + =. 1; // nullptr a is a constant // nullptr a *. 5; // . 4.nullptr_t not a pointer type (although looks like a pointer type are used up) func_ptr (( a float*) nullptr a); // OK, T = a float. nullptr can be converted to any type of pointer // func_ptr (nullptr); // fails to compile type nullptr is nullptr_t, instead of a pointer type // compiler does not "smart" to derive certain types of indicators (including * void) func_value ( 0 ); // T = int; func_value (nullptr); // T = nullptr_t; func_value (( a float *) nullptr); // T * = a float return 0 ; } / * output nullptr of type: STD = :: nullptr_t the sizeof (nullptr a). 4 = NewPtr nullptr a == ! NewPtr <nullptr a * /
Two, nullptr with NULL
The difference between (a) nullptr with a NULL
1. NULL is a macro definition, C ++ which is usually defined as 0 , the compiler always give priority to it as an integer constant (C defined by the following criteria (void *) 0).
2. nullptr is a compile-time constants, of type nullptr_t . It is not an integer type, not a pointer type .
3. In the template derivation in, nullptr a nullptr_t be derived as type , you can still be converted to the implicit cursor. But 0 or NULL will be derived as an integer type .
4. To avoid overloads between integers and pointers . Since NULL will be matched to the integer version of the function parameter, instead of the expected release pointer.
(B) nullptr with (void *) 0 difference
1. nullptr a any pointer conversion is implicit . (Although not nullptr pointer type, but can still be used when the pointer)
2. (void *) 0 is just a cast expression that returns void * pointer type, only through conversion to other types of pointer to use .
[Difference] nullptr programming experiment with a NULL
#include <the iostream> #include <Memory> #include <the mutex> #include <The iomanip> // for SetBase; the using namespace STD; // 3. avoid overloading between integers and pointers void F ( int ) { COUT < < " Invoke F (int) " << endl; } void F ( void * ) { COUT << " Invoke F (void *) " << endl; } // 4. performance nullptr a template class the Widget {} ; int f1(std::shared_ptr<Widget> spw) { return 0; } double f2(std::unique_ptr<Widget> upw) { return 0; } bool f3(Widget* pw) { return true; } using MuxGuard = std::lock_guard<std::mutex>; template<typename Func, typename Mux, typename Ptr> decltype(auto) lockAndCall(Func func, Mux& mux, Ptr ptr) //C++14 { MuxGuard guard(mux); return func(ptr); } int main() { //1. nullptr是一个右值常量 nullptr_t my_nullptr; COUT << " & my_nullptr = " << SetBase ( 16 ) << endl << & my_nullptr; // Object nullptr_t address-type // COUT << SetBase (16) << endl << & nullptr a; // nullptr a rvalue is constant, can not take the address. const nullptr_t && def_nullptr = nullptr a; // nullptr a rvalue is constant, reference can be used to pick the right value. << COUT " & def_nullptr = " << SetBase ( 16 ) << endl << & def_nullptr; // can take the reference value of the right address (named variable itself is left value) // 2. nullptr a and (void *) 0 of difference void * PX = NULL; Compilation error, can not implicitly be converted to void * type int * int * PZ = ( int *) PX; // void * can not be implicitly converted to int *, must be cast! int * PI = nullptr; // the ok! nullptr can be converted to any other implicit pointer type void * PV = nullptr; // ! OK nullptr implicitly converted to any other type of pointer // 3. Avoid integers and pointers between the overloaded function F ( 0 ); / / Invoke F (int) F (NULL); // Invoke F (int) F (( char *) 0 ); // Invoke F (void *) F (nullptr a); // Invoke F (void *) // 4. nullptr of template derived, when the pointer is still used. the mutex :: M1 STD, M2, M3; // Auto lockAndCall RESULT1 = (F1, M1, 0); // 0 is derived type int, and share_ptr <Widget> type mismatch // Auto result2 lockAndCall = (F2, M2, NULL); // supra, NULL is preferentially for an integer Auto result3 = lockAndCall (F3, M3, nullptr a); // nullptr a be derived as nullptr_t, but such can be converted to the implicit * the Widget return 0 ; } / * output & my_nullptr = 00DEFB28 & def_nullptr = 00DEFB10 Invoke F (int) Invoke F (int) Invoke F (void *) Invoke F (void *) * /