我正在编写一个小型库,我想在编译器支持它时使用类枚举。我还想使用其他C ++ 11功能,例如final
和override
关键字。
到目前为止,我已经使用了一些技巧来确保它在所有版本的GCC上编译,但是当我启动Windows分区时,Visual Studio 2010也开始抱怨。以下是我使用的技巧示例:
#if __GNUC__ == 4 && (__GNUC_MINOR__ > 7 || \
(__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ > 1))
# define TATO_OVERRIDE override
# define TATO_NO_THROW nothrow
#else
# define TATO_OVERRIDE
# define TATO_NO_THROW throw()
#endif
我知道最新版本的Visual Studio也支持一批新功能。我想拥有的是一组宏,它告诉我在我使用的编译器上有哪些功能。
#ifdef THIS_COMPILER_SUPPORTS_CLASS_ENUMS
...
#endif
这是否存在?是否有图书馆可以做到这一点?
编译器的文档?
让我澄清一下。我知道如何找到这些信息,我的问题在其他地方。我不想通过每个可能的编译器文档来收集这些信息,特别是因为相同的编译器可能支持与其版本相关的不同功能。这是我到目前为止所做的,而我所寻找的实际上是一种不这样做的方式。
答案 0 :(得分:4)
Boost实际上有a wide range of such macros可用。你可以用它。否则,唯一的方法是基本上检查编译器的版本,并使用您对该版本支持的功能的了解来确定某个功能是否可用。
基本上,除了手动之外,Boost会做什么。
答案 1 :(得分:3)
有人讨论过一些标准化的功能测试机制,但事实证明这没有任何意义:如果编译器实现了标准,那么所有功能测试都会产生true
。如果没有,则没有理由认为它在功能测试方面遵循标准!
因此,使用某种配置文件似乎是最可靠的方法。就个人而言,我会采用与显式检查编译器版本不同的方式:相反,我会尝试使用某些东西来尝试编译器是否支持特定功能到可接受的程度。配置可以autoconf
或类似的方式运行。
关于生成的配置,我会尝试将事物映射到合适的构造,而不是在配置头之外使用条件编译。例如,我会使用这样的东西:
#if defined(KUHL_HAS_CLASS_FINAL)
# define kuhl_class_final final
#else
# define kuhl_class_final
#endif
特别是对于类枚举,您可能需要使用一些有点棘手的东西,因为枚举值只能在范围内使用,而值只能在范围外使用。因此,可能有必要在一个案例中提出某种形式的额外嵌套而不是另一个案例。
答案 2 :(得分:1)
clang有一些用于各种功能检查的内置宏:clang feature-check macros 如果所有编译器供应商都能选择这些(以及更多),那就太好了。
答案 3 :(得分:0)
“我想拥有的是一组宏,告诉我我正在使用的编译器上有哪些功能。”
标准中没有这样的东西。
编译器差异的一种实用方法是为您支持的每个编译器和编译器版本提供一个标头。这些标头应具有相同的名称。包含哪一个取决于包含路径,工具用法,这对于每个编译器都很容易定制。
我将此概念称为虚拟标题。我发现它适用于三个级别:系统依赖,编译器依赖和版本依赖。我认为该计划不会扩展到更多,但另一方面,这似乎是人们所需要的。