http://boost.ez2learn.com/libs/config/doc/html/boost_config/boost_macro_reference.html
以下宏都是用於描述C++標準所要求的某個特性的,如果下面當中的某一個宏被定義,則表示該編譯器存在一個與標準不符的缺陷。
宏 |
節 |
說明 |
---|---|---|
|
編譯器 |
編譯器存在某些偏特化方面的缺陷 - 很可能是 Borland C++ Builder. |
|
編譯器 |
如果在當前域中有對被查找符號的 using 聲明,則ADL查找失敗。例如, |
|
編譯器 |
編譯器定位並查找那些在執行參數相關查找時實際上不應查找的名字空間。 |
|
編譯器 |
編譯器沒有實現ADL(又稱Koenig查找); 請見 std::3.4.2 [basic.koenig.lookup] |
|
標準庫 |
如果編譯器/標準庫提供非標準或有問題的 |
|
平臺 |
平臺不提供字符分類操作的函數 |
|
編譯器 |
如果針對cv-限定類型的模板特化與針對非cv-限定類型的特化衝突。 |
|
編譯器 |
如果針對cv-void類型的模板特化與針對void的特化衝突。 |
|
平臺 |
平臺不提供 |
|
平臺 |
平臺不提供 |
|
編譯器 |
編譯器不能編譯帶有受限基類的嵌套類: template<typename T> struct foo : { template<typename U> struct bar : public U {}; }; |
|
編譯器 |
模板值參數不能爲受限類型,例如: template<class T, typename T::type value> class X { ... }; |
|
標準庫 |
標準庫未將 |
|
編譯器 |
編譯器不支持異常處理(多數嵌入式平臺的C++編譯器都要求這一設置)。注意,並不要求 boost 庫一定要遵守這一配置設置 - 在某些情形下這樣做是不可能的。遵守這一設置的庫通常在發生嚴重錯誤時會退出 - 已經警告你了! |
|
編譯器 |
在調用函數模板實例時只能使用被推導的模板參數。 |
|
編譯器 |
編譯器不執行函數模板分類(function template ordering)或執行的方法不正確。 // #1 template<class T> void f(T); // #2 template<class T,class U> void f(T(*)(U)); void bar(int); f(&bar); // 應選擇 #2. |
|
編譯器 |
編譯器違犯 std::9.4.2/4. |
|
編譯器 |
C++實現不提供 |
|
標準庫 |
標準庫缺少 |
|
標準庫 |
標準庫缺少 |
|
編譯器 |
C++編譯器不支持抽像類型的 SFINAE, 見 Core Language DR337, 不過它當前還未加入標準。幸好多數編譯器支持 SFINAE 也支持這份 DR. |
|
標準庫 |
C++實現不提供 |
|
標準庫 |
在編譯期,像 |
|
標準庫 |
沒有 |
|
編譯器 |
編譯器不支持模板類的單獨成員函數特化。 |
|
編譯器 |
如果編譯器支持成員模板,但是在訪問成員模板類時不使用 template 關鍵字。 |
|
編譯器 |
不支持C++標準 14.5.3 所描述的成員模板友元語法 ( |
|
編譯器 |
不完全支持成員模板函數。 |
|
標準庫 |
沒有 |
|
編譯器 |
編譯器要求繼承的操作符友元函數在名字空間域中定義,然後 using 給 boost. 可能是 GCC 的特殊方式。相關例子請見 |
|
編譯器 |
編譯器不能正確處理那些依賴於主模板中的缺省參數的偏特化。 |
|
編譯器 |
編譯器不能正確處理常量成員函數的指針,要防止在重載函數模板時使用它們。相關例子請見 |
|
編譯器 |
成員指針不能作爲模板參數使用。 |
|
編譯器 |
編譯器誤讀了 8.5.1, 將含私有或保護的成員函數的類視爲 non-aggregate. |
|
編譯器 |
編譯器不支持 "Substitution Failure Is Not An Error" 的元編程慣用法。 |
|
標準庫 |
C++標準庫沒有提供符合標準的 |
|
標準庫 |
平臺沒有符合標準的 |
|
標準庫 |
C++ 實現不提供 |
|
標準庫 |
編譯器不提供符合標準的 |
|
標準庫 |
標準庫沒有 |
|
標準庫 |
標準庫沒有符合標準的 |
|
標準庫 |
C++標準庫不提供 |
|
標準庫 |
如果標準庫的輸出迭代器不是可賦值的,就定義它。 |
|
標準庫 |
<typeinfo> 頭文件將 |
|
標準庫 |
標準庫沒有符合標準的 |
|
標準庫 |
標準庫沒有 |
|
標準庫 |
標準庫沒有 |
|
編譯器, 平臺 |
C++中的C庫函數標準頭文件(即 |
|
標準庫 |
C++實現不提供 |
|
平臺 |
平臺沒有符合標準的 |
|
編譯器 |
不支持類模板偏特化(14.5.4 [temp.class.spec]). |
|
標準庫 |
標準庫不提供模板化的 iostream 類。 |
|
標準庫 |
標準庫沒有爲容器提供模板化的迭代器結構函數。 |
|
編譯器 |
編譯器不支持模板模板參數。 |
|
編譯器 |
編譯器根本不支持 typeid 操作符。 |
|
編譯器 |
如果 return 語句不可到達,則不要求必須有 return 語句,但是有些編譯器堅持要有,如果發生這種情形,會導致一串警告。 |
|
編譯器 |
編譯器不接受用 using 聲明將一個函數從基類的 typename 帶入到派生類中,如果派生類中已經有同名的函數。 |
|
編譯器 |
編譯器不接受用 using 聲明將一個模板類或模板函數從另一個名字空間導入。原本 Borland 存在導入到全局名字空間或從全局名字空間導入的問題,後來擴展以 MSVC6,它存在導入模板類(但不是模板函數)的問題。 |
|
編譯器 |
編譯器不允許一個 void 函數返回對另一個 void 函數的調用結果。 void f() {} void g() { return f(); } |
以下宏描述了不被C++標準要求的一些特性。該宏只在該特性存在時被定義。
宏 |
節 |
說明 |
---|---|---|
|
平臺 |
平臺支持 BeOS 風格的線程。 |
|
平臺 |
平臺有 POSIX API |
|
編譯器 |
編譯器用 |
|
平臺 |
平臺有 POSIX 頭文件 |
|
平臺 |
平臺有函數 |
|
平臺 |
平臺有 Win32 API |
|
平臺 |
平臺有 POSIX API |
|
標準庫 |
C++實現提供了 (SGI) hash_set 和 hash_map 類。該宏被定義時, |
|
平臺 |
平臺有函數 |
標準庫 |
標準庫沒有符合標準的 |
|
|
編譯器 |
編譯器支持 |
|
平臺 |
平臺有 POSIX API nanosleep. |
|
平臺 |
平臺有 |
|
編譯器 |
表示編譯器支持具名返回值優化(NRVO). 用於爲某些函數選擇最高效的實現。相關例子請見 |
|
標準庫 |
標準庫有部分符合標準的 |
|
平臺 |
平臺有 POSIX API |
|
平臺 |
平臺有 POSIX API |
|
平臺 |
平臺有 POSIX API |
|
平臺 |
平臺支持 POSIX 風格的線程。 |
|
平臺 |
平臺有 POSIX API |
|
編譯器, 標準庫 |
編譯器有對 SGI 風格的 type traits 有原生支持。 |
|
平臺 |
平臺有 |
|
標準庫 |
C++實現提供了 (SGI) slist 類。該宏被定義時, |
|
標準庫 |
標準庫沒有符合標準的 |
|
標準庫 |
標準庫有符合 TR1 的 |
|
標準庫 |
標準庫的 |
|
標準庫 |
標準庫的 |
標準庫 |
標準庫有符合 TR1 的引用包裝器,在 |
|
|
標準庫 |
標準庫有符合 TR1 的 result_of 模板,在 |
|
標準庫 |
標準庫有符合 TR1 的 mem_fn 函數模板,在 |
|
標準庫 |
標準庫有符合 TR1 的 bind 函數模板,在 |
|
標準庫 |
標準庫有符合 TR1 的 function 類模板,在 |
|
標準庫 |
標準庫有符合 TR1 的 hash 函數模板,在 |
|
標準庫 |
標準庫有符合 TR1 的 |
|
標準庫 |
標準庫有符合 TR1 的 |
|
標準庫 |
標準庫有符合 TR1 的 |
|
標準庫 |
標準庫有符合 TR1 的 |
|
標準庫 |
標準庫有符合 TR1 的 |
|
標準庫 |
標準庫有符合 TR1 的對 |
|
標準庫 |
標準庫有符合 TR1 的 |
|
標準庫 |
標準庫有符合 TR1 的 |
|
標準庫 |
表示所有其它 |
|
平臺, 編譯器 |
如果編譯器在當前編譯模式下支持多線程執行,則被定義。 |
|
標準庫 |
標準庫沒有符合標準的 std::use_facet, 但有完成該工作的兩參數版本。主要用於 Rogue Wave 標準庫。 |
|
平臺 |
平臺提供了 |
|
平臺 |
平臺支持 MS Windows 風格的線程。 |
|
標準庫 |
使用的是 Microsoft 的有問題的 |
|
編譯器 |
Microsoft Visual C++ 6.0 的成員模板特性(客氣地說)足以定義 |
|
平臺 |
1998 C++ 標準中沒有頭文件 |
以下宏描述了很可能被包含在即將到來的 ISO C++ 標準 C++0x 中,但尚未經批准加入到語言中的一些特性。
宏 |
說明 |
---|---|
|
編譯器支持概念。 |
以下宏描述了在即將到來的 ISO C++ 標準 C++0x 中,但尚未被某個特定編譯器支持的一些特性。
宏 |
說明 |
---|---|
|
編譯器不支持類型 |
|
編譯器不支持類型 |
|
編譯器不支持 |
|
編譯器不支持 |
|
編譯器不支持缺省( |
BOOST_NO_DELETED_FUNCTIONS |
編譯器不支持已刪(= delete ) 函數。 |
|
編譯器不支持顯式轉換操作符( |
|
編譯器不支持模板顯式實例化聲明 ( |
|
編譯器不支持 |
|
編譯器不支持裸字符串文字。 |
|
編譯器不支持右值引用。 |
|
編譯器不支持定域枚舉( |
|
編譯器不支持 |
|
編譯器不支持 Unicode ( |
|
編譯器不支持可變參數數量的模板。 |
以下宏爲簡單的輔助宏,或是爲編譯器/標準庫的缺陷提供變通方法的宏。
宏 |
說明 |
---|---|
|
有些編譯器不支持推斷上下文中爲受限類型使用 |
|
包含獲得 SGI |
|
包含獲得 SGI |
|
包含獲得 SGI |
|
用於標準庫擴展(hashtable 類等)的名字空間。 |
|
在不允許類中靜態整型常量成員初始化的編譯器上,我們必須使用 enums 作爲變通的方法,如果我們想獲得編譯期的常量。該宏給了我們一個方便的方法來聲明這樣的常量。例如,將: struct foo{ static const int value = 2; }; 替換爲: struct foo{ BOOST_STATIC_CONSTANT(int, value = 2); }; |
|
一般被擴展爲空,但如果編譯器要求即使不可到達也要一個返回語句,則擴展爲 return x; |
|
有些編譯器在模板參數未出現在函數參數列表中時,會自動將不同的函數模板實例"摺疊"起來。例如: #include <iostream> #include <ostream> #include <typeinfo> template <int n> void f() { std::cout << n << ' '; } template <typename T> void g() { std::cout << typeid(T).name() << ' '; } int main() { f<1>(); f<2>(); g<int>(); g<double>(); } 在VC++ 6上會錯誤地輸出 "2 2 double double ". 這些宏可以在函數參數列表中使用,修正這一問題且不影響調用的語法。例如,將上例改寫爲: template <int n> void f(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, n)) { ... } template <typename T> void g(BOOST_EXPLICIT_TEMPLATE_TYPE(T)) { ... } 它們會聲明(對於受影響的編譯器)一個虛擬的缺省參數,所以它們 |
|
如果標準庫沒有符合標準的 |
|
如果標準庫沒有符合標準的 |
|
有些支持成員模板的編譯器並不能使用 |
|
在對 |
|
該宏將兩個參數聯接起來,即使其中有的參數本身也是宏(請見C++標準的16.3.1)。可用於創建一個名字與象 __LINE__ 這樣的預定義宏結合。 |
以下宏描述了一些 boost 特性;一般來說,這些 boost 宏只用於在用戶代碼中進行檢測之用。
宏 |
頭文件 |
說明 |
---|---|---|
|
|
以 XXYYZZ 格式描述 boost 版本號如下: |
|
|
沒有64位整數類型 |
|
|
如果在 |
|
|
如果編譯器爲 Microsoft Visual C++, 但不是其它定義了 |
|
|
如果編譯器爲 Intel compiler, 則定義該宏,其中帶有與編譯器版本宏相同的值。 |
|
|
如果 Windows 平臺 API 可用,則定義該宏。 |
|
|
如果使用的是 dinkumware 標準庫,則定義該宏,如果 Dinkumware 庫版本宏 |
|
|
如果 regex 庫不支持寬字符正則表達式,則定義該宏。 |
|
|
定義爲一個字符串,描述在用編譯器的名字和版本。主要用於驗證配置。 |
|
|
定義爲一個字符串,描述在用標準庫的名字和版本。主要用於驗證配置。 |
|
|
定義爲一個字符串,描述平臺的名字。主要用於驗證配置。 |
以下宏和輔助頭文件專門給那些包含獨立源代碼的庫的作者使用,其目的是解決兩個問題:修正被編譯庫的ABI,以及根據編譯器的設置選擇 哪一個已編譯的庫進行鏈接。
在與一個預編譯的庫進行鏈接時,關鍵是構建該庫時編譯器所用的ABI必須與使用該庫的代碼所用的ABI嚴格匹配。這裏的ABI指的是, 象結構壓縮排 列、命名擾亂機制、某些類型的大小(如 enum 類型)等東西。這些東西與線程支持、運行期庫的變化等是分離的,後者必須通過構建變量來處理。爲了解釋得更清楚,一個編譯器(如Borland的)有許多 編譯器選項會對ABI造成很微妙的影響,理論上至少有3200種組合,這還沒有考慮運行期庫的變化。幸好,這些變量可以通過 #pragma
來管理,告訴編譯器在你的庫中所聲明的類型使用了怎樣的ABI。爲了避免在 boost 頭文件中到處出現 #pragma
,
我們用一些前綴頭文件和後綴頭文件來完成這項工作。典型的用法如下:
my_library.hpp
#ifndef MY_INCLUDE_GUARD #define MY_INCLUDE_GUARD // 這裏是要包含的頭文件:#include <boost/config.hpp>
#include <whatever>#include <boost/config/abi_prefix.hpp>
// 必須是最後一個 #include namespace boost { // 這裏是你的代碼 }#include <boost/config/abi_suffix.hpp>
// 彈出 abi_prefix.hpp 的 pragmas #endif // include guard
my_library.cpp
... // 在實現文件中不需要任何特殊處理 ...
用戶可以通過定義 BOOST_DISABLE_ABI_HEADERS
來禁止這一機制,或者他們可以定義 BOOST_ABI_PREFIX
和/或 BOOST_ABI_SUFFIX
來指向它們自己的前綴/後綴頭文件,如果他們想要的話。
當用戶鏈接到一個庫的某個構建時,本質上該庫構建時所鏈接的運行期庫必須與他們的應用所鏈接的一樣 - 如果不是這樣的話,該庫與他們的代碼就不是二進制兼容的 - 很可能他們的應用會在運行時發生異常。這種問題的調測非常耗費時間,也很困難,常常會導致用戶和作者同樣的失敗(選擇正確的庫來鏈接並不像看起來那麼容 易,它們通常有6-8個選擇,有些用戶並不清楚它們會有不同的選擇)。
爲了解決這個問題,有些編譯器允許源代碼包含 #pragma
以指示鏈接器要鏈接哪一個庫,用戶要做的只是包含他們所需的頭文件,將已編譯的庫放在他的庫搜索路徑中,剩下的交給編譯器和鏈接器去做就行了。 Boost.config
通過頭文件 <boost/config/auto_link.hpp>
支持這一方法,在包含這一頭文件之前,要定義以下一個或多個宏:
BOOST_LIB_NAME
-
必選:包含庫的基本名的一個標識符,例如 'boost_regex'.
BOOST_DYN_LINK
-
可選:要設置鏈接 dll 而不是靜態庫時。
BOOST_LIB_DIAGNOSTIC
-
可選:要設置頭文件打印出選定的庫的名字時(用於調試)。
如果編譯器支持這種機制,那麼它將被告知鏈接到適當名字的庫,用於生成庫名的實際算法在 <boost/config/auto_link.hpp>
中有相關說明,它必須與通過
bjam 的安裝規則進行庫的創建所用的算法相匹配。
my_library.hpp
... // // 如果用戶已通過定義 BOOST_ALL_NO_LIB 或 BOOST_MY_LIBRARY_NO_LIB 來禁止, // 或者這是我們自己的源代碼(以 BOOST_MY_LIBRARY_SOURCE 來表示),則不包含自動 // 自動鏈接代碼: // #if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_MY_LIBRARY_NO_LIB) && !defined(BOOST_MY_LIBRARY_SOURCE) # define BOOST_LIB_NAME boost_my_library # ifdef BOOST_MY_LIBRARY_DYN_LINK # define BOOST_DYN_LINK # endif # include <boost/config/auto_link.hpp> #endif ...
my_library.cpp
// 定義 BOOST_MY_LIBRARY_SOURCE 以便頭文件得知該庫正在構建 // (可能是導出而不是導入代碼) // #define BOOST_MY_LIBRARY_SOURCE #include <boost/my_library/my_library.hpp> ...