我无法从 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
。此外,类型本身仅通过 nullptr
literal 的语义定义。这些语义是否仍然适用于未初始化的值?
为什么这个问题在实践中并不重要
您不想声明 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 typestd::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/