是否有用于检测C ++ 11x支持的预处理器指令?

时间:2012-05-23 09:53:15

标签: c++ gcc c-preprocessor preprocessor-directive

如果有一些代码我想尽可能多地使用C ++ 11x扩展,但如果不支持则会有后备。目前,GCC的OSX版本和VisualC编译器几乎不支持C ++ 11x,所以我使用:

#if (defined(__APPLE__) || (defined(_WIN32)))
   ...fallback code without C++11x ...
#else
   ... code using C++11x ...
#endif

这很有效,但这不是正确的事情,特别是因为MacPorts中的gcc编译器支持c ++ 11x。

是否有#define C11X_SUPPORTED类型的宏?也许GCC只有一些东西?

3 个答案:

答案 0 :(得分:49)

__cplusplus应该在前C ++ 11编译器中定义为199711L,在那些支持C ++ 11的版本中201103L。这在实践中是否有很大帮助是另一个问题:大多数编译器只在那里,所以不应该将其定义为201103L,即使它们支持您感兴趣的功能。并且它不是闻所未闻的编译器谎言:例如,编译器将其定义为199711L并且不支持export模板。但是功能测试没有标准功能。

最简单的解决方案是,在确定所有编译器都支持之前,不要使用任何特定的新功能。无论如何,你必须编写并支持后备代码;为什么保持两个版本。此规则的一个例外可能是影响性能的新功能:编译器是否支持移动语义。在这种情况下,我建议使用编译器相关的包含文件,您可以根据编译器文档和个人测试自行编写;仅仅因为编译器可能会记录它支持特定功能并不意味着它的支持是无错误的。只需为每个目标编译器创建一个目录,将此文件放在那里,并在makefile或项目文件中指定相应的-I/I选项。

你的测试应该是:

#ifdef HAS_MOVE_SEMANTICS
...
#endif

而不仅仅是编译器,版本或其他。

答案 1 :(得分:25)

您可以检查__cplusplus宏的值。对于C ++ 11,它大于199711L

类似

#if __cplusplus > 199711L

#endif

答案 2 :(得分:7)

Boost.Config库提供了granular preprocessor macros,您可以根据给定C ++ 11特性的存在来有条件地编译。

(对于编译器,C ++ 11支持不一定是全有或全无。例如,考虑Microsoft cherry picked which C++11 features如何根据他们认为最有利于客户的内容包含在Visual Studio 2012中。 )