是否有用于检测 C++11x 支持的预处理器指令?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10717502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a preprocessor directive for detecting C++11x support?
提问by Kenneth
If have some code where I would like to use C++11x extensions as much as possible, but have a fallback if this is not supported. Currently the OSX version of GCC and the VisualC compiler has little to no support for C++11x, so I use:
如果有一些代码,我想尽可能多地使用 C++11x 扩展,但如果不支持,请回退。目前 OSX 版本的 GCC 和 VisualC 编译器几乎不支持 C++11x,所以我使用:
#if (defined(__APPLE__) || (defined(_WIN32)))
...fallback code without C++11x ...
#else
... code using C++11x ...
#endif
And this works, but is not really the right thing to do, especially since the gcc compiler in MacPorts DOES support c++11x.
这有效,但并不是真正正确的做法,尤其是因为 MacPorts 中的 gcc 编译器确实支持 c++11x。
Is there a #define C11X_SUPPORTED
type macro? Perhaps something only GCC has?
有#define C11X_SUPPORTED
类型宏吗?也许只有 GCC 才有?
回答by James Kanze
__cplusplus
should be defined as 199711L
in pre-C++11 compilers, 201103L
in those suporting C++11. Whether this is much help in practice is another question: most compilers are only halfway there, so shouldn't be defining it as 201103L
, even if they support the features you are interested in. And it's not unheard of for a compiler to lie: a compiler which defines it as 199711L
and doesn't support export
for templates, for example. But there's no standard feature by feature test.
__cplusplus
应该199711L
在 C++11 之前的编译器中定义,201103L
在那些支持 C++11 的编译器中。这在实践中是否有很大帮助是另一个问题:大多数编译器只完成了一半,因此不应将其定义为201103L
,即使它们支持您感兴趣的功能。编译器撒谎并非闻所未闻:a例如,将其定义为199711L
不支持export
模板的编译器。但是功能测试没有标准功能。
The simplest solution is just not to use any particular new feature until you can be sure that all compilers support it. You have to write and support the fallback code anyway; why maintain two versions. The one exception to this rule might be new features which impact on performance: whether the compiler supports move semantics or not. In such cases, I'd suggest a compiler dependent include file, which you write yourself based on the compiler documentation and personal tests; just because the compiler may document that it supports a specific feature doesn't mean that its support is bug-free. Just create a directory per targeted compiler, put this file there and specify the appropriate -I
or /I
option in your makefile or project file.
最简单的解决方案就是不要使用任何特定的新功能,直到您确定所有编译器都支持它。无论如何,您必须编写并支持回退代码;为什么要维护两个版本。这一规则的一个例外可能是影响性能的新特性:编译器是否支持移动语义。在这种情况下,我建议使用依赖于编译器的包含文件,您可以根据编译器文档和个人测试自行编写该文件;仅仅因为编译器可能记录它支持特定功能并不意味着它的支持没有错误。只需为每个目标编译器创建一个目录,将这个文件放在那里,并在你的 makefile 或项目文件中指定适当的-I
或/I
选项。
And your tests should be something along the lines of:
你的测试应该是这样的:
#ifdef HAS_MOVE_SEMANTICS
...
#endif
rather than just on the compiler, version or whatever.
而不仅仅是在编译器、版本或其他方面。
回答by Luchian Grigore
You can check the value of the __cplusplus
macro. For C++11, it's greater than 199711L
.
您可以检查__cplusplus
宏的值。对于 C++11,它大于199711L
.
So something like
所以像
#if __cplusplus > 199711L
#endif
回答by Edward Brey
The Boost.Configlibrary provides granular preprocessor macrosyou can use to conditionally compile based on the presence of a given C++11 feature.
该Boost.Config库提供细粒度预处理宏,你可以使用基于给定的C ++ 11特征的存在有条件编译。
(For a compiler, C++11 support need not be an all or nothing proposition. For example, consider how Microsoft cherry picked which C++11 featuresto include in Visual Studio 2012 based on what they believed would most benefit their customers.)
(对于编译器,C++11 支持不一定是全有或全无的主张。例如,考虑一下 Microsoft 如何根据他们认为最有利于客户的内容挑选哪些 C++11 特性包含在 Visual Studio 2012 中。 )