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

Ken*_*eth 49 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
Run Code Online (Sandbox Code Playgroud)

这可行,但不是真正正确的事情,特别是因为MacPorts中的gcc编译器支持c ++ 11x.

#define C11X_SUPPORTED型宏吗?也许GCC只有一些东西?

Jam*_*nze 53

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

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

你的测试应该是这样的:

#ifdef HAS_MOVE_SEMANTICS
...
#endif
Run Code Online (Sandbox Code Playgroud)

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

  • 这就是我所说的,海湾合作委员会最近改变了谎言,而以前它说实话.原因是无法判断它是否说实话没有实现C++ 98,或说实话没有实现C++ 11.现在,您可以区分实现C++ 98的时间,以及何时说明不实现C++ 11的真相.YIPPEE.我认为没有人曾经实现过C++ 98(或C++ 03),所以`__cplusplus`的确切值基本没用.它始终是特定于实现或说谎. (7认同)

Luc*_*ore 26

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

所以像

#if __cplusplus > 199711L

#endif
Run Code Online (Sandbox Code Playgroud)

  • 还有一点需要注意,编译器已经知道谎言. (8认同)
  • 但需要注意的是,还没有*全部支持. (3认同)
  • @juanchopanza 是的,这绝不保证完全支持 C++11,或者编译器完全支持 C++11(但它可能是你能得到的最好的)。 (2认同)

Edw*_*rey 8

Boost.Config库提供细粒度预处理宏,你可以使用基于给定的C++ 11特征的存在有条件编译.

(对于编译器,C++ 11支持不一定是一个全有或全无的命题.例如,考虑一下Microsoft如何根据他们认为最有利于客户的内容选择在Visual Studio 2012中包含哪些C++ 11特性. )