在C ++ 11标准中,我不理解为什么不允许使用nullptr的地址,而允许一个 获取他们自己的std :: nullptr_t实例的地址。除了nullptr是保留关键字这一事实之外,是否有任何指定的推理作出此决定?
仅仅因为它让我很开心,我试图用以下功能环绕这个限制:
decltype(nullptr)* func(const decltype(nullptr) &nref) noexcept
{
return const_cast<decltype(nullptr)*>(reinterpret_cast<const decltype(nullptr)*>(&nref));
}
我不得不在参数上使用reinterpret_cast,因为没有它我会得到歇斯底里的错误:
error: invalid conversion from 'std::nullptr_t*' to 'std::nullptr_t*' [-fpermissive]
当我通过直接传递 nullptr 来调用此函数时,每次都会得到一个不同的地址。是否为nullptr动态分配地址及时进行比较等?或者(可能更有可能)编译器可能强制使用底层对象的临时副本?
当然,这些都不是至关重要的信息,我觉得有趣的是为什么要实施这一特定的限制(以及为什么我会看到我的行为)。
答案 0 :(得分:79)
即使您在赋予5
之后可以获取int
的地址,也与无法获取5
的地址相同。 nullptr_t
没有替代值没有关系。
值没有地址;对象。
将这样的值传递给const &
参数时生成临时对象,或者将值绑定到const引用,例如static_cast< T const & >( … )
或声明命名引用{{1} }。您看到的地址是临时地址。
答案 1 :(得分:27)
如果您正在接受标准答案,§18.2/ 9会非常坦率地提出您的观察结果:
虽然无法获取nullptr的地址,但是作为左值的另一个nullptr_t对象的地址可以 被采取。
或者,§2.14.7说明nullptr
:
指针文字是关键字nullptr。它是std :: nullptr_t类型的prvalue。
那么什么是prvalue? §3.10/ 1回答:
prvalue(“纯”rvalue)是一个不是xvalue的rvalue。 [示例:调用函数的结果 其返回类型不是引用是prvalue。诸如12,7.3e5或true之类的文字的值是 也是一个prvalue。 - 结束例子]
希望尝试获取示例中任何内容的地址将更有意义地说明为什么不能取nullptr
的地址。这是这些例子的一部分!
答案 2 :(得分:10)
nullptr
是一个(文字)常量,它们没有内存地址,就像代码中的任何其他文字常量一样。它与0
类似,但与特殊std::nullptr_t
类型而不是void*
类似,以避免重载问题(指针与整数)。
但如果您使用值nullptr
定义自己的变量,则它具有内存地址,因此您可以获取其地址。
同样适用于任何其他类型的任何其他文字常量(在C ++中属于 prvalue 类别),因为文字常量不是存储在程序中 (只作为它们出现的表达式的一部分),这就是为什么谈论地址没有任何意义。但是,常量变量确实有地址,以指出差异。
答案 3 :(得分:4)
true和false都是关键字,而文字则是类型(bool)。 nullptr是std :: nullptr_t类型的指针文字,它是一个prvalue(你不能使用&amp;取得它的地址),nullptr也是prvalue所以你不能取其地址,文字常量不会存储在你的程序中
拥有地址没有意义。