2015-10-13 78 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>