有没有办法在编译时检测编译器是否支持C++ 11的某些功能?例如,像这样:
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
Run Code Online (Sandbox Code Playgroud)
Cyg*_*gon 120
有一个常量命名为__cplusplusC++编译器应该设置为支持的C++标准版本,请参阅此内容
#if __cplusplus <= 199711L
#error This library needs at least a C++11 compliant compiler
#endif
Run Code Online (Sandbox Code Playgroud)
它在Visual Studio 2010 SP1中设置为199711L,但我不知道供应商是否会如此大胆地增加它,如果他们只有(部分)编译器级支持而不是具有所有C++ 11更改的标准C++库.
因此,在另一个答案中提到的Boost的定义仍然是唯一明智的方法来确定是否存在对C++ 11线程和标准的其他特定部分的支持.
Jam*_*lis 51
Boost.Config有许多宏可用于测试对特定C++ 11功能的支持.
Pao*_*o M 38
如C++ 11标准(§iso.16.8)所述:
编译C++转换单元时,名称__cplusplus被定义为值201103L.
使用该宏的值,您可以检查编译器是否符合C++ 11.
现在,如果您正在寻找一种标准方法来检查编译器是否支持C++ 11功能的任何子集,我认为没有标准的,可移植的方式; 您可以检查编译器文档或std库头文件以获取更多信息.
Jar*_*ryd 31
我知道这是一个非常古老的问题,但这个问题可能经常出现,答案有点过时了.
具有C++ 14标准的较新编译器具有检查功能的标准方法,包括C++ 11功能.综合页面位于https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
总之,每个功能都有一个可以检查的标准宏#ifdef.例如,要检查用户定义的文字,可以使用
#ifdef __cpp_user_defined_literals
Run Code Online (Sandbox Code Playgroud)
小智 20
检查支持C++ 14等.在GCC上进行测试5.2.1.
#include <iostream>
int main(){
#if __cplusplus==201402L
std::cout << "C++14" << std::endl;
#elif __cplusplus==201103L
std::cout << "C++11" << std::endl;
#else
std::cout << "C++" << std::endl;
#endif
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*per 17
我刚刚编写了一个小测试套件来检查特定编译器支持哪些C++ 11功能.但是,这当然是一个"预编译时"检查.
https://github.com/sloede/cxx11tests
Don*_*uck 15
你可以用这个:
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
cout << "C++11 is supported";
#else
cout << "C++11 is not supported";
#endif
Run Code Online (Sandbox Code Playgroud)
对于C++ 11,除Visual Studio之外的大多数编译器都将__cplusplus宏设置为201103L,但是任何版本的Visual Studio都将其设置199711L为C++ 11之前用于其他编译器的值.此代码将_cplusplus宏与201103L除Visual Studio之外的所有编译器进行比较,如果编译器是Visual Studio,则会检查Visual Studio的版本是否晚于2015,Visual Studio的第一个版本是否完全支持C++ 11(对于Visual Studio 2015,_MSC_VER宏有价值1900,看这个答案).
小智 7
如果您不想使用Boost.Config并且需要测试支持C++ 11的编译器,那么检查常量的值__cplusplus就可以了.但是,编译器可能支持C++ 11标准的大多数流行功能,但它不支持整个规范.如果要为尚未100%兼容C++ 11规范的特定Visual Studio编译器启用支持,请使用以下代码片段,该代码片段允许在Visual Studio 2013中进行编译:
#if defined(_MSC_VER)
# if _MSC_VER < 1800
# error This project needs atleast Visual Studio 2013
# endif
#elif __cplusplus <= 199711L
# error This project can only be compiled with a compiler that supports C++11
#endif
Run Code Online (Sandbox Code Playgroud)
如何检测是否使用Visual Studio 2008编译代码,提供了Visual Studio编译器的完整版本列表
在传统的Linux/Unix世界中,autoconf传统上用于测试库和编译器功能的存在以及将它们放入您在文件中根据需要使用的config.h中的错误.
当 2011 年 2 月提出这个问题时,对 C++11 的支持并不一致。编译器需要时间来赶上标准,因此与此同时,他们发布了部分支持。例如,编译器可能已经实现了可变参数模板,但没有auto。
如果您的代码依赖于 C++11 功能的子集,则您没有标准方法来询问编译器是否专门支持它们。
\n您可以使用来检查整体C++11 支持#if __cplusplus >= 201103L,但是:
__cplusplus功能支持时才设置为\xe2\x80\x94,而且还没有人拥有完整功能支持。因此,如果您使用它,您将不必要地拒绝人们想要用来编译您的代码的大多数或全部编译器。201103L一个实用的解决方案是使用第三方Boost.Config库,该库维护了一堆功能测试宏。Boost.Config\ 的维护人员跟踪哪些编译器支持哪些功能,并相应地为每个Boost.Config版本更新宏。
(有关 Boost 的内容基于@James McNellis的早期答案,现已删除。
\n如今,每个主要编译器都有一个支持整个 C++11 标准的版本。。
\n如果您的代码需要任何C++11,那么现在要求编译器支持所有C++11 是合理的。所以,使用#if __cplusplus >= 201103L. (有关此宏的标准参考,请参阅 @Paulo M\ 的答案。)但请注意MSVC \xe2\x80\x94存在复杂性,请参阅 @Donald Duck\ 的答案。
从C++20开始,除了粗粒度的__cplusplus宏之外,你还可以#include <version>得到一堆特性测试宏。这基本上是基于标准的替代方案Boost.Config。
根据Jarryd 的回答,这些宏实际上至少在某些 2016 时代的 C++14 编译器中可用。
\n