53

如果有一些代码我想尽可能多地使用 C++11x 扩展,但如果不支持则有一个后备。目前 OSX 版本的 GCC 和 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 才有?

4

3 回答 3

55

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

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

你的测试应该是这样的:

#ifdef HAS_MOVE_SEMANTICS
...
#endif

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

于 2012-05-23T10:04:54.260 回答
29

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

所以像

#if __cplusplus > 199711L

#endif
于 2012-05-23T09:54:10.780 回答
8

Boost.Config库提供了细粒度的预处理器宏,可用于根据给定 C++11 功能的存在进行有条件的编译。

(对于编译器而言,C++11 支持不一定是全有或全无的主张。例如,考虑 Microsoft 樱桃如何根据他们认为最有利于客户的内容来选择 Visual Studio 2012 中包含的 C++11 功能。 )

于 2013-05-21T02:24:18.983 回答