zoukankan      html  css  js  c++  java
  • C++11 nullptr与nullptr_t

      参考《深入理解C++11》

      NULL是一个宏定义,在传统C头文件stddef.h中定义如下:

    #undef NULL
    #ifdef(__cplusplus)
    #define NULL 0
    #else
    #define NULL ((void *)0)
    #endif

      可以看到,NULL可能被定义为字面常量0,或者定义为无类型指针(void*)常量。这就使得在使用NULL时有些问题:

       在main函数中,f(NULL)调用的起始是第二个函数,因为在C++98中,字面常量0具有二义性:既可以是一个整型,也可以是一个无类型指针(void*)。如果想要调用f(char*)的话,需要对字面常量0进行强制类型转换:(void*)0 然后再调用,否则编译器总会优先把0看做一个整型常量。

    nullptr_t的定义:头文件:<cstddef>

      typedef decltype(nullptr) nullptr_t;

      使用nullptr_t时必须包含头文件:<cstddef>,但是使用nullptr时则不用,因为nullptr是关键字。nullptr是有类型的,且仅可以被隐式转化为指针类型,在编写C++11代码时,使用nullptr替换NULL将使得代码更健壮。

    • nullptr:指针空值常量
    • nullptr_t:指针空值类型,也就是nullptr的类型,见上面的定义

    nullptr_t注意事项:

     示例代码:

        char* cp = nullptr;
    
        //不可转换为整型,而任何类型也不能转换为nullptr_t
        //以下代码不能通过编译
        //int n1 = nullptr;
        //int n2 = reinterpret_cast<int>(nullptr);
    
        //nullptr与nullptr_t类型变量可以作比较
        //当使用 ==  <=  >=符号比较时返回true
        nullptr_t nptr;
        if (nptr == nullptr)
        {
            cout << "nullptr_t nptr == nullptr" << endl;
        }
        else
        {
            cout << "nullptr_t nptr != nullptr" << endl;
        }
        if (nptr < nullptr)
            cout << "nullptr_t nptr < nullptr" << endl;
        else
            cout << "nullptr_t nptr !< nullptr" << endl;
    
        //不能转换为整型或bool类型,以下代码不能通过编译
        //if(0 == nullptr)
        //if(nullptr)
    
        //不能进行算术运算,以下代码不能通过编译
        //nullptr += 1;
        //nullptr *5;
    
        //以下操作均可正常运行
        size_t size1 = sizeof(nullptr);
        typeid(nullptr);
        throw(nullptr);

    注:如果上述代码注释部分能通过编译,可能是编译器版本不够新,在C++11中不允许上述注释代码。

       虽然nullptr_t看起来像是个指针类型,但是在把nullptr_t应用于模板中时,模板会把它作为一个普通的类型来进行推导,并不会将其视为T*指针。

    template<typename T>
    void g(T* t){}
    
    template<typename T>
    void h(T t){}
    
    int main(int argc, char *argv[])
    {
        g(nullptr);         //编译失败,nullptr的类型是nullptr_t,而不是指针
        g((float*) nullptr);//推导出T=float
    
        h(0);               //推导出T=int
        h(nullptr);         //推导出T=nullptr_t
        h((float*)nullptr); //推导出T=float*
    }
  • 相关阅读:
    Factory——工厂方法
    Subsets II
    【算法设计】快速计算积分图
    Win8驱动的兼容性问题
    Matplotlib快速上手
    Pandas —— (8)数据读取
    Pandas —— (7)数据分组
    Pandas —— (6)多个DataFrame的合并、连接、去重、替换
    Pandas —— (4)常用数学、统计方法
    Pandas —— (3)数据查看、转置、添加、修改、删除、运算(对齐)、排序
  • 原文地址:https://www.cnblogs.com/zyk1113/p/13489015.html
Copyright © 2011-2022 走看看