std::nullptr_t 是 c++11 引入的独立空指针字面量类型,唯一值为 nullptr,可隐式转换为任意指针类型但不可转为算术类型,专用于消除重载和模板推导中的二义性。

std::nullptr_t 是什么类型?
std::nullptr_t 是 C++11 引入的一个空指针字面量的类型,它唯一合法的值就是 nullptr。它不是整数类型,也不是指针类型,而是一个独立的、可隐式转换为任意指针类型(包括成员指针)的 空类型。
它的设计目标很明确:让 nullptr 在函数重载和模板推导中能被准确识别,避免 NULL(通常定义为 0 或 0L)带来的二义性问题。
为什么不能用 void* 或 int 来表示 nullptr?
如果 nullptr 的类型是 void*,它就无法隐式转换到成员函数指针(void (T::*)());如果它是 int,又会和整型重载冲突。而 std::nullptr_t 正好填补了这个空白:
- 可隐式转换为任意对象指针、函数指针、成员指针
- 不可转换为算术类型(比如不能赋给
int) - 不可用于算术运算(
nullptr + 1编译报错) - 大小通常是 1 字节(但标准未规定,仅保证可空)
在函数重载中怎么体现它的作用?
这是 std::nullptr_t 最典型的使用场景。看下面这个例子:
本文档主要讲述的是Python开发网站指南;HTML是网络的通用语言,一种简单、通用的全置标记语言。它允许网页制作人建立文本与图片相结合的复杂页面,这些页面可以被网上任何其他人浏览到,无论使用的是什么类型的电脑或浏览器 Python和其他程序语言一样,有自身的一套流程控制语句,而且这些语句的语法和其它程序语言类似,都有for, if ,while 类的关键字来表达程序流程。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
立即学习“C++免费学习笔记(深入)”;
void foo(int) { std::cout << "int\n"; }
void foo(char*) { std::cout << "char*\n"; }
void foo(std::nullptr_t) { std::cout << "nullptr_t\n"; }
<p>foo(0); // 调用 int 版本
foo(nullptr); // 调用 nullptr_t 版本(不会歧义成 char<em>)
foo(NULL); // 可能调用 int 或 char</em>,取决于 NULL 定义没有 std::nullptr_t 重载时,foo(nullptr) 会退化为匹配 char*(因为 nullptr 可转为 char*),但有了专属重载后,编译器优先选择最精确匹配——即 std::nullptr_t 版本。
模板推导和类型检查中要注意什么?
模板参数推导时,nullptr 的类型始终是 std::nullptr_t,这点必须明确:
-
auto x = nullptr;→x类型是std::nullptr_t -
template<typename t> void bar(T); bar(nullptr);</typename>→T推导为std::nullptr_t -
static_assert(std::is_same_v<decltype std::nullptr_t>);</decltype>→ 成立 - 但
std::is_pointer_v<:nullptr_t></:nullptr_t>是false,别误以为它是指针类型
容易忽略的一点:std::nullptr_t 是一个 cv-unqualified 类型,所以 const std::nullptr_t 和 std::nullptr_t 是不同类型,虽然它们都能接收 nullptr 值。









