c++ - nullptr_t 是默认的可构造类型吗?

标签 c++ gcc clang nullptr

我无法从 C++11 标准中判断 nullptr_t 是否具有默认构造函数。换句话说,以下是否有效?:

nullptr_t n; 

GCC 和 VC++ 允许使用上述代码,但 clang 不允许。我在标准中找不到任何指定它没有默认构造函数的东西,而我能找到的表明它应该有。这对我很重要,因为我正在编写 nullptr 的基本后备实现以支持旧编译器,并且需要知道是否需要为其提供默认构造函数。

最佳答案

标准的内容

标准说 (18.2)

nullptr_t is defined as follows:

namespace std {
   typedef decltype(nullptr) nullptr_t;
}

The type for which nullptr_t is a synonym has the characteristics described in 3.9.1 and 4.10.

3.9.1 基本上说它应该和 void* 的大小相同,而 4.10 则指定了 nullptr 的转换规则。

编辑: 3.9.9 进一步明确指出 nullptr_t 是标量类型,这意味着适用于 8.5 中内置类型的预期初始化规则:

  • 默认初始化 (nullptr_t n;),它使 n 的值未定义。正如 Johannes Schaub 正确指出的那样,这与最新版本的 Clang 编译得很好。
  • 值初始化(nullptr_t n = nullptr_t();),将 n 初始化为 0。

此行为与例如int,所以 nullptr_t 绝对是默认可构造的。 这里有趣的问题是:nullptr_t 具有未定义的值是什么意思?归根结底,nullptr_t 只有一个有意义的可能值,即 nullptr。此外,类型本身仅通过 nullptrliteral 的语义定义。这些语义是否仍然适用于未初始化的值?

为什么这个问题在实践中并不重要

您不想声明 nullptr_t 类型的新变量。该类型唯一有意义的语义已经通过 nullptr 字面量表达,因此无论何时使用 nullptr_t 类型的自定义变量,您都可以使用 nullptr.

实践中重要的是什么

唯一的异常(exception)是您可以采用 nullptr_t 类型的非类型模板参数。对于这种情况,了解哪些值可以转换为 nullptr_t 很有用,这在 4.10 中进行了描述:

A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. [...] A null pointer constant of integral type can be converted to a prvalue of type std::nullptr_t.

这基本上就是你所期望的:你可以写

nullptr_t n = 0;    // correct: 0 is special

但不是

nullptr_t n = 42;   // WRONG can't convert int to nullptr_t

gcc 4.6 和 Clang SVN 都做到了这一点。

关于c++ - nullptr_t 是默认的可构造类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9953068/

相关文章:

c++ - 在 C++ 中调用作为结构数组成员的成员函数指针的语法是什么

c++ - super 对撞机二维阵列 : generative nesting : wrap/size issues

c++ - GCC-4.7 编译错误

gcc - 使用ffmpeg库编译报错

C++ 类型索引散列导致未定义的行为

c++ - 在 C++ 的头文件和 Cpp 文件中使用类

c++ - 为什么在 C++ 中混合 size_t 和 unsigned int 时模除法会出错

c - 如何获得有关分配给但不再使用的变量的警告?

c++ - 为什么使用 clang -std=gnu++11 时此 C++ 代码会编译?

linux - 从剥离的 ELF 二进制文件估计编译器(GCC 或 LLVM-clang)版本