有點史前史。nullptr_t駐留在哪裏?
我已經寫了很長一段時間的遊戲引擎。它分爲幾個靜態庫,如「utils」,「rsbin」(資源系統),「窗口」,然後鏈接到一個可執行文件中。
這是一個跨平臺引擎,被編爲Windows和Android版。 在Windows下,我使用MinGW進行編譯。在Android下,使用CCTools,它是本地gcc的接口。
其中一個基類是utils::RefObject
,它代表了一個類似於Windows的IUnknown的概念:它提供了一個引用計數器來確定它的生存期以及從基類指針查詢特定接口的方法。還有template< typename T > utils::Ref
,專門爲這類物體設計的。它包含一個std::atomic< utils::RefObject* >
,並在施工,分配和銷燬時自動更新其對象的重新計數,類似於std::shared_ptr
。它還允許通過查詢方法隱式轉換不同類型的RefObjects。雖然,查詢對象的類型是低效的,因此,utils::Ref
會重載其大多數運算符,例如, G。有具體utils::Ref<T>::Ref(T* ptr)
構造函數,它只是增加了傳遞的對象的引用計數,和一般utils::Ref<T>::Ref(RefObject* ptr)
,該查詢其對於T的實例論證並拋出失敗異常(不要擔心,雖然,有當然是爲軟鑄的方法)。
但只具有這兩種方法引入了一個問題:你不能明確地用一個空指針初始化utils::Ref
,因爲它是不明確的;所以也有utils::Ref<T>::Ref(nullptr_t)
提供一種方法來做到這一點。
現在,我們正在解決手頭的問題。在頭文件中,原型與上面拼寫完全一樣,沒有任何前面的std::
。請注意,我也不使用using namespace
。很長一段時間,這工作。
現在,我正在研究圖形系統。它之前就已經存在,但它是相當基本的,所以我甚至沒有注意到<gl.h>實際上只定義的OpenGL 1.1,而新版本你應該通過<glext.h>。現在,有必要使用後者。但包括它打破了舊的參考類。
從錯誤信息來看,MinGW的現在有在原型,nullptr_t
問題。我在網上做了一個快速搜索,發現通常是它被稱爲std::nullptr_t
。儘管並非到處都是。
快速sumup:我有沒有nullptr_t
無論std::
或using namespace
編譯罰款,直到我包括頭前<glext.h>。
我一直使用至今的網站,cplusplus.com/reference,表明全球::nullptr_t
is exactly how it should be。另一方面,en.cppreference.com wiki tells that它實際上是std::nullptr_t
。
簡單的測試程序,以void foo(int)
和void foo(nullptr_t)
一個HelloWorld,無法編譯,現在的理由是明確的"error: 'nullptr_t' was not declared in this scope"
與建議,使用std::nullptr_t
代替。
在需要的地方添加std::
並不難;但這種情況讓我頗爲好奇。
cplusplus.com實際上在撒謊? =>在回答中回答,是的。這是一個不準確的來源。
然後,如果nullptr_t
實際上位於namespace std
,爲什麼utils::Ref
編譯? =>通過評論中的建議,運行了一些測試,發現<互斥體>,包含在某個其他頭文件中,當放置在任何stddef頭之前時,定義全局爲::nullptr_t
。當然不是一個理想的行爲,但它不是一個主要的錯誤。無論如何應該向MinGW/GCC開發者彙報。
爲什麼包含<glext.h>會打破它? =>當<互斥量012xx之前包含任何stddef頭時,該類型根據標準定義爲std::nullptr_t
。 <glext.h>包括<windows.h>,它反過來肯定包含stddef頭,其中包含WinAPI需要的其他包。
下面是源,在問題定義的類:
- utils/ref.hpp
- utils/ref.cpp
- utils/refobject.hpp
- utils/refobject.cpp
- utils/logger.hpp =>這一個使用一個互斥,以避免在線撕開輸出。
- utils/cbase.hpp
(包括後者2等都可能影響太)
作爲評價建議的,我跑克++ -E在其上編一個測試用例,並且發現了一個很有趣的位在<STDDEF.H>:
#if defined(__cplusplus) && __cplusplus >= 201103L
#ifndef _GXX_NULLPTR_T
#define _GXX_NULLPTR_T
typedef decltype(nullptr) nullptr_t;
#endif
#endif /* C++11. */
我們尋找到_GXX_NULLPTR_T
被別人定義......快速GREP通過MinGW的的文件,並沒有發現什麼,除了這STDDEF.H
因此,爲什麼以及如何禁用它仍然是個謎。特別是當只包括<stddef.h>而沒有別的沒有定義nullptr_t
任何地方,儘管上面的位。
查看預處理輸出以查看引入了':: nullptr_t'的位置。 – tenfour 2015-02-24 13:09:23
FWIW,cplusplus.com因不準確而聞名。 – Angew 2015-02-24 13:14:27
它屬於std,非零的可能性,該源代碼首先看到另一個編譯器首先在頭文件中使用了'std :: nullptr_t;'。像MSVC++一樣。 – 2015-02-24 13:20:03