nullptr 是 c++11 起唯一类型安全的空指针字面量;null 是整数宏,易导致重载歧义、模板推导失败及隐式类型错误,而 nullptr 具有 std::nullptr_t 类型,仅可转为指针,保障类型安全与现代 c++ 兼容性。

直接说结论:nullptr 是 C++11 起唯一类型安全的空指针字面量;NULL 是宏,本质是整数 0,在重载、模板、智能指针等现代 C++ 场景下会引发歧义甚至编译失败。
为什么 func(NULL) 有时调用的是 func(int) 而不是指针版本
因为 NULL 在绝大多数 C++ 标准库实现中被定义为 0(不是 (void*)0),它是一个整型常量。当存在两个重载函数时:
void func(int)void func(char*)
调用 func(NULL) 会被编译器视为传入整数 0,于是优先匹配 func(int) —— 这不是你想要的行为。
nullptr 没这个问题:它的类型是 std::nullptr_t,只能隐式转换为指针类型,所以 func(nullptr) 必定调用 func(char*)。
std::unique_ptr 和 std::function 构造时必须用 nullptr
这些模板类依赖精确的类型推导。用 NULL 会导致编译失败或静默错误:
-
std::unique_ptr<int> p = nullptr;</int>✅ 正确 -
std::unique_ptr<int> p = NULL;</int>❌ 编译报错:no viable conversion -
std::function<void> f = nullptr;</void>✅ 可赋值为空(表示无目标) -
std::function<void> f = NULL;</void>❌ 推导成int,不匹配构造函数签名
原因在于 NULL 触发整型推导,而 nullptr 的 std::nullptr_t 类型能被模板正确识别并转换为所需指针语义。
nullptr 不能当整数用,这是设计,不是限制
你写 int x = nullptr; 会直接编译失败,这不是 bug,而是强制类型安全:
-
nullptr可隐式转为任意原始指针(int*、void*、成员指针等) -
nullptr不能转为int、long、bool(除非显式比较,如if (p == nullptr)) -
nullptr + 1、*nullptr都非法 —— 这些操作本就不该对空指针成立
而 NULL 允许 int x = NULL;、if (NULL == 42) 等,看似方便,实则掩盖逻辑错误。
最容易被忽略的一点:即使代码用 NULL 能编译通过,Clang 和 GCC 在启用 -Wzero-as-null-pointer-constant 时会警告;现代静态分析工具也默认将 NULL 视为可疑代码。真正的问题往往不出现在初始化那一刻,而出现在某次新增重载或迁移到智能指针时突然爆发。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











