C++17常量
nullptr出现的目的是为了替代NULL。在某种意义上来说,传统会把NULL,0视为同一种东 西,这取决于编译器如何定义NULL,有些编译器会将定义为((void*)0),有些则会直接将其定义 为0。
C++不允许直接将void*隐式转换到其他类型。但如果编译器尝试把NULL定义为((void*)0), 那么在下面这句代码中:
char *ch = NULL;
没有了void*隐式转换的C++只好将定义为0。而这依然会产生新的问题,将NULL定义成0,将导致C++中重载特性发生混乱。考虑下面这两个函数:
void foo(char*);
void foo(int);
那么foo(NULL)这个语句将会去调用foo(int),从而导致代码违反直觉。
为了解决这个问题,C++引入了关键字nullptr,专门用来区分空指针、0。而nullptr的类型 为nullptr_t,能够隐式的转换为任何指针或成员指针的类型,也能和他们进行相等或者不等的比较。 你可以尝试使用clang++编译下面的代码:
#include <iostream>#include <type_traits>//*******1. nullptr******/
// C++17 引入了 std::nullptr_t 类型,它是一个空指针类型。
// 在 C++ 中,NULL 是一个宏,通常定义为 0 或 (void*)0。
/*int main(){if(std::is_same<decltype(NULL), decltype(0)>::value){std::cout << "NULL is the same type as 0" << std::endl;}else{std::cout << "NULL is NOT the same type as 0" << std::endl;//NULL 和 0 在 C++ 中是不同的类型。}if(std::is_same<decltype(NULL), decltype((void*)0)>::value){std::cout << "NULL is the same type as (void*)0" << std::endl;}else{std::cout << "NULL is NOT the same type as (void*)0" << std::endl;//NULL 和 (void*)0 在 C++ 中是不同的类型。}if(std::is_same<decltype(NULL), std::nullptr_t>::value){std::cout << "NULL is the same type as std::nullptr_t" << std::endl;}else{std::cout << "NULL is NOT the same type as std::nullptr_t" << std::endl;//NULL 和 std::nullptr_t 在 C++ 中是不同的类型。}return 0;
}
*/
从输出中我们可以看出,NULL不同于与nullptr,0。所以,请养成直接使用的习惯。 此外,在上面的代码中,我们使用了decltype和std::is_same这两个属于现代C++的语法,简 单来说decltype用于类型推导,而std::is_same用于比较两个类型是否相同,我们会在后面 一节中详细讨论。