我无法从 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
.
Edit:3.9.9 还明确指出nullptr_t
是标量类型,这意味着 8.5 中内置类型的预期初始化规则适用:
- 默认初始化 (
nullptr_t n;
),剩下的值为n
不明确的。正如 Johannes Schaub 正确指出的那样,这可以与最新版本的 Clang 很好地编译。
- 值初始化 (
nullptr_t n = nullptr_t();
),将 n 初始化为 0。
此行为与例如相同int
, so nullptr_t
绝对是默认可构造的。
这里有趣的问题是:这意味着什么nullptr_t
具有未定义的值?归根结底,只有一个有意义的可能值nullptr_t
,即nullptr
。此外,类型本身仅通过语义来定义nullptr
文字。这些语义是否仍然适用于未初始化的值?
为什么这个问题在实践中并不重要
您不想声明类型的新变量nullptr_t
。该类型唯一有意义的语义已经通过nullptr
字面量,因此每当您使用类型的自定义变量时nullptr_t
,你也可以使用nullptr
.
实践中重要的是什么
唯一的例外是您可以采用类型的非类型模板参数nullptr_t
。对于这种情况,了解哪些值可以转换为很有用nullptr_t
,在 4.10 中描述:
空指针常量是整数类型的整型常量表达式 (5.19) 纯右值,其计算结果为零或类型的纯右值std::nullptr_t
。 [...]
整型的空指针常量可以转换为类型的纯右值std::nullptr_t
.
这基本上就是你所期望的:你可以写
nullptr_t n = 0; // correct: 0 is special
but not
nullptr_t n = 42; // WRONG can't convert int to nullptr_t
gcc 4.6 和 Clang SVN 都做到了这一点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)