我无法从 C++11 标准中判断 nullptr_t 是否具有默认构造函数。换句话说,以下是否有效?:
nullptr_t n;
GCC 和 VC++ 允许使用上述代码,但 clang 不允许。我在标准中找不到任何指定它没有默认构造函数的东西,而我能找到的表明它应该有。这对我很重要,因为我正在编写 nullptr 的基本回退实现以支持旧编译器,并且需要知道是否需要为其提供默认构造函数。
标准说(18.2)
nullptr_t 定义如下:
namespace std { typedef decltype(nullptr) nullptr_t; }
nullptr_t 是同义词的类型具有 3.9.1 和 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。此行为与 eg 相同int
,因此nullptr_t
绝对是可默认构造的。这里有趣的问题是:nullptr_t
具有未定义的值意味着什么?归根结底,只有一个有意义的可能值nullptr_t
,即nullptr
。此外,类型本身仅通过nullptr
文字的语义来定义。这些语义是否仍然适用于未初始化的值?
你不想声明一个新的 type 变量nullptr_t
。该类型唯一有意义的语义已经通过nullptr
字面量表达,因此无论何时使用自定义变量 type nullptr_t
,都可以使用nullptr
.
唯一的例外是您可以采用 type 的非类型模板参数nullptr_t
。对于这种情况,了解哪些值可以转换为 是很有用的nullptr_t
,这在 4.10 中进行了描述:
空指针常量是整数类型的整数常量表达式 (5.19) 纯右值,其计算结果为零或类型的纯右值
std::nullptr_t
。[...] 整数类型的空指针常量可以转换为 prvalue 类型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 都做到了这一点。
虽然nullptr
是语言本身的新添加,std::nullptr_t
只是未命名类型的别名,声明的别名cstddef
如下:
typedef decltype(nullptr) nullptr_t;
虽然nullptr_t
作为 typedef 而不是语言关键字,它没有被列为基本类型,但它被指定为基本类型(而不是,例如,指针类型或类类型)。因此它没有默认构造函数,但您仍然可以像之前那样声明变量。您的变量未初始化,我想知道它的用途是什么以及您从clang
.
另请参见此处。