2015-10-13 79 views
4

我看到微软的stddef.h定义nullptr_t这样的:'nullptr_t`应该是全局命名空间的一部分吗?

namespace std 
{ 
    typedef decltype(__nullptr) nullptr_t; 
} 

using ::std::nullptr_t; 

using decleration注入nullptr_t到全局命名空间。我无法在标准中找到任何说明应该完成的事情。

我还看到在GCC nullptr_t不在全局命名空间中。

这两种实现都可以被允许或者是其中的一个bug? 我的不好,GCC的行为与CL相同。


编辑:用cstddef同样的情况,下面编译罚款与VC(online too)。

#include <cstddef> 

int main() 
{ 
    nullptr_t nil = nullptr; 
} 
+0

'使用:: std :: nullptr_t;'和'使用std :: nullptr_t;'有区别吗?很好的问题btw。 – gsamaras

+0

@gsamaras我不认为有什么区别。 – Motti

+0

在这方面没有区别。如果你有'namespace foo {namespace std {using nullptr_t = int}使用std :: nullptr_t; }'。 –

回答

7

它必须位于全局命名空间中。

D.5 C标准库头[depr.c.headers]

2每个C头,其每一个具有形式name.h的名称,行为就好像每个名称放置在标准库名称空间由相应的cname标题放置在全局名称空间范围内。 [...]

对于特定于C++的名称,这里没有例外。如果C++为<stddef.h>不提供的<cstddef>添加一个名称,那么C++的<stddef.h>仍然需要提供它。

+0

它也被注入''的全局命名空间。 – Motti

+1

@Motti是的,这是允许的。 ''标题必须在'std'命名空间中定义名称,并且还可以在全局名称空间中定义它们。 ''标头必须在全局名称空间中定义它们,并且还可以在'std'命名空间中定义它们。 – hvd

2

我还看到在GCC中nullptr_t不在全局名称空间中。

您确定吗?

https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/ginclude/stddef.h;hb=HEAD#l436

你可能有GCC的旧版本,我看到它在那里GCC 4.8.0及更高版本。

的情况与此相同cstddef,

这不能保证工作。要使用便携式::nullptr_t,您必须包含<stddef.h>。要便携地使用std::nullptr_t,您必须包含<cstddef>