我无法从C ++ 11标准中看出nullptr_t是否有默认构造函数。换句话说,以下是否有效?:
nullptr_t n;
GCC和VC ++允许上面的代码,但clang没有。我在标准中找不到任何指定它没有默认构造函数的东西,我能找到它表明它应该。这对我很重要,因为我正在编写一个基于nullptr的基本回退实现,用于较旧的编译器支持,需要知道我是否需要给它一个默认的构造函数。
答案 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。