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> ...