Lesson 9 nullptr_t and nullptr

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 *) 
* /

Guess you like

Origin www.cnblogs.com/5iedu/p/11277428.html