NULL在C++中存在二义性,因其本质是宏(常定义为0或(void*)0),在函数重载时可能错误匹配int参数而非指针参数;nullptr通过引入独立类型std::nullptr_t,仅可隐式转换为指针类型、不可转为整数,彻底消除该歧义。

为什么 NULL 在 C++ 中会有二义性
因为 NULL 本质是宏,常见定义为 0 或 (void*)0。当重载函数同时接受 int 和指针类型时,传入 NULL 编译器可能选错重载版本——比如匹配到 void func(int) 而非 void func(char*)。
std::nullptr_t 是如何解决这个问题的
std::nullptr_t 是一个空类型,仅能隐式转换为任意指针类型(含成员指针),但**不转换为整数类型**。所以当你写 func(nullptr),编译器只能匹配指针参数的重载,彻底避开整数歧义。
-
nullptr的类型就是std::nullptr_t,它不是整数,也不是指针,而是一个独立字面量类型 - 所有接受指针的函数、模板、
delete、new表达式都原生支持nullptr - 不能对
nullptr做算术运算(如nullptr + 1报错),这比NULL更安全
替换 NULL 时要注意的兼容细节
直接全局替换 NULL → nullptr 看似简单,但有几处容易翻车:
- 宏定义中用到
NULL(比如#define LOG(ptr) printf("%p", (ptr) ? ptr : NULL))——nullptr不能直接传给%p,需转成void*:改为static_cast(nullptr) - C 头文件混用场景:如果头文件被 C 和 C++ 共同包含,
nullptr在 C 中不合法,此时仍需保留NULL,或用#ifdef __cplusplus分支处理 - 模板推导中,
nullptr推导为std::nullptr_t,而NULL可能推导为int,影响 SFINAE 或std::is_pointer_v判断
一个典型二义性修复示例
看这个重载函数:
foo(NULL)
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











