c++如何使用std::nullptr_t_c++空指针类型详解【原理】

13次阅读

std::nullptr_t 是 c ++11 引入的空指针字面量类型,仅具 nullptr 一个值,非整数也非指针,需 std:: 前缀访问,用于消除重载二义性。

c++ 如何使用 std::nullptr_t_c++ 空指针类型详解【原理】

std::nullptr_t 是什么类型,为什么不能直接写 nullptr_t

std::nullptr_t 是 C++11 引入的 ** 空指针字面量类型 **,它只有一种合法值:nullptr。它不是整数类型,也不是指针类型,而是一个独立的、可隐式转换为任意指针类型的空类型。

常见错误是试图这样写:

std::nullptr_t x = nullptr;

——这本身没错;但若写成

nullptr_t x = nullptr;

就会报错,因为 nullptr_t 不在全局作用域,必须带 std:: 前缀(除非你用 using std::nullptr_t;)。

关键点:nullptr 是字面量,std::nullptr_t 是它的类型,二者不可互换使用。

如何用 std::nullptr_t 重载函数区分空指针和整数 0?

老式 NULL(即 00L)导致函数重载二义性,std::nullptr_t 提供了明确的重载分支:

立即学习 C++ 免费学习笔记(深入)”;

void foo(int) {std::cout << "intn";} void foo(char*) {std::cout << "char*n";} void foo(std::nullptr_t) {std::cout << "nullptrn";}

调用效果:

  • foo(0) → 调用 int 版本
  • foo(nullptr) → 精确匹配 std::nullptr_t 版本
  • foo(NULL) → 取决于实现(可能为 intchar*),不推荐

这是 std::nullptr_t 最实用的场景:让接口对空指针有显式、无歧义的语义支持。

能否把 std::nullptr_t 当作模板参数或类型别名?

可以,但它非常“单薄”——除了能转成指针,几乎不能做任何事:

  • 不能取地址:&nullptr 是非法的
  • 不能定义数组:std::nullptr_t arr[3] 编译失败
  • 可以作为模板参数:
    template<typename T> struct holder {T val;}; holder<std::nullptr_t> h{nullptr};
  • 可以 typedef / using:
    using null_type = std::nullptr_t;

    ,但意义有限,因为无法构造其他值

它本质上是个“标记类型”,设计目的就是唯一、轻量、可转换,不是为了承载数据。

为什么 sizeof(std::nullptr_t) 通常是 1,且不能继承?

std::nullptr_t 是个空类类型(empty class type),标准只要求它满足“可隐式转换为任意指针类型”,未规定大小,但主流实现(GCC、Clang、MSVC)都设为 1 字节,以满足对象必须有唯一地址的要求。

它不可派生:

struct bad : std::nullptr_t {};

会编译失败,因为标准明确禁止继承 std::nullptr_t(它是 final 类型,尽管未显式写 final,但语言规则限制其不可继承)。

这点容易被忽略:它不是普通类,而是语言内建的特殊类型,行为由标准硬性约束,而非实现自由发挥。

text=ZqhQzanResources