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

时间:2012-03-31 04:38:32

标签: c++ gcc clang nullptr

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

nullptr_t n; 

GCC和VC ++允许上面的代码,但clang没有。我在标准中找不到任何指定它没有默认构造函数的东西,我能找到它表明它应该。这对我很重要,因为我正在编写一个基于nullptr的基本回退实现,用于较旧的编译器支持,需要知道我是否需要给它一个默认的构造函数。

2 个答案:

答案 0 :(得分:17)

标准所说的

标准说(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。

此行为与例如int,所以nullptr_t绝对可以默认构建。 这里有趣的问题是:nullptr_t具有未定义的值意味着什么?在一天结束时,nullptr_t只有一个有意义的可能值,即nullptr。此外,类型本身仅通过nullptr文字的语义来定义。这些语义是否仍然适用于单元化值?

为什么这个问题在实践中无关紧要

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

在实践中有什么关系

唯一的例外是您可以使用nullptr_t类型的非类型模板参数。对于这种情况,了解哪些值可以转换为nullptr_t很有用,这在4.10中有描述:

  

空指针常量是整数类型的整数常量表达式(5.19)prvalue,其计算结果为零或类型为std::nullptr_t的prvalue。 [...]   可以将整数类型的空指针常量转换为std::nullptr_t类型的prvalue。

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

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都是正确的。

答案 1 :(得分:1)

虽然nullptr是语言本身的新增内容,但std::nullptr_t只是未命名类型的别名,在cstddef中声明的别名如下:

typedef decltype(nullptr) nullptr_t;

虽然作为typedef而不是语言关键字的nullptr_t未被列为基本类型,但它被指定为基本类型(而不是,例如,作为指针类型或类类型)。因此它没有默认构造函数,但您仍然可以声明一个像您所做的变量。你的变量没有被初始化,我想知道它的用途是什么以及你从clang得到了什么错误信息。

另见here