如何检查C ++ 11支持?

时间:2011-02-19 00:26:28

标签: c++ c++11

有没有办法在编译时检测编译器是否支持C ++ 11的某些功能?例如,像这样:

#ifndef VARIADIC_TEMPLATES_SUPPORTED

#error "Your compiler doesn't support variadic templates.  :("

#else

template <typename... DatatypeList>
class Tuple
{
    // ...
}

#endif

11 个答案:

答案 0 :(得分:114)

有一个名为__cplusplus的常量,C ++编译器应该设置为支持的C ++标准版本see this

#if __cplusplus <= 199711L
  #error This library needs at least a C++11 compliant compiler
#endif

在Visual Studio 2010 SP1中设置为199711L,但我不知道供应商是否会如此大胆地增加它,如果他们只有(部分)编译器级支持而不是标准C ++库和所有C + +11更改。

So Boost在另一个答案中提到的定义仍然是唯一能够确定是否支持C ++ 11线程和标准的其他特定部分的唯一方法。

答案 1 :(得分:53)

Boost.Config具有a plethora of macros,可用于测试对特定C ++ 11功能的支持。

答案 2 :(得分:37)

C ++ 11 标准所述(§iso.16.8):

  

名称 __ cplusplus 定义为值 201103L 时   编译C ++翻译单元。

使用该宏的值,您可以检查编译器是否符合C ++ 11。

现在,如果您正在寻找一种标准方法来检查编译器是否支持C ++ 11功能的任何子集,我认为没有标准的,可移植的方式;您可以查看编译器文档或std库头文件以获取更多信息。

答案 3 :(得分:31)

我知道这是一个非常古老的问题,但这个问题可能经常出现,答案有点过时了。

具有C ++ 14标准的较新编译器具有检查功能的标准方法,包括C ++ 11功能。综合页面位于https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations

总之,每个功能都定义了一个标准宏,您可以使用#ifdef进行检查。例如,要检查用户定义的文字,可以使用

#ifdef __cpp_user_defined_literals

答案 4 :(得分:20)

用于检查支持C ++ 14和其他。在GCC上进行测试5.2.1。

select * from temp_new_template_pattern 
where vin_pattern in (
select vin_pattern
from temp_new_template_pattern 
group by vin_pattern 
having count(*) > 1)

答案 5 :(得分:17)

我刚刚编写了一个小测试套件来检查特定编译器支持哪些C ++ 11功能。但是,这当然是“预编译时”检查。

https://github.com/sloede/cxx11tests

答案 6 :(得分:15)

您可以使用:

#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
    cout << "C++11 is supported";
#else
    cout << "C++11 is not supported";
#endif

对于C ++ 11,除Visual Studio之外的大多数编译器都将__cplusplus宏设置为201103L,但任何版本的Visual Studio都将其设置为199711L,这是其他值C ++ 11之前的编译器。对于除Visual Studio之外的所有编译器,此代码将_cplusplus宏与201103L进行比较,如果编译器是Visual Studio,则会检查Visual Studio的版本是否晚于2015,Visual Studio的第一个版本它完全支持C ++ 11(对于Visual Studio 2015,_MSC_VER宏的值为1900,请参阅this answer)。

答案 7 :(得分: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

How to Detect if I'm Compiling Code With Visual Studio 2008

提供了Visual Studio编译器的完整版本列表

答案 8 :(得分:6)

在传统的Linux / Unix世界中,autoconf传统上用于测试库和编译器功能的存在以及将它们放入您在文件中根据需要使用的config.h中的错误。

答案 9 :(得分:2)

快速历史

在 2011 年 2 月提出这个问题时,对 C++11 的支持不一致。编译器需要时间来赶上标准,因此在此期间,他们发布了部分支持。例如,编译器可能实现了可变参数模板,但没有实现 auto

如果您的代码依赖于 C++11 功能的一个子集,您就没有标准的方式来询问编译器是否特别支持它们。

您可以check使用#if __cplusplus >= 201103L整体支持 C++11,但是:

  • 直到 2011 年 8 月该标准被接受后,该常数及其含义才在技术上正式确定。
  • 这太粗糙了。编译器可能只有在获得完整功能支持后才将 __cplusplus 设置为 201103L——而且还没有人获得完整的功能支持。因此,如果您使用它,您将不必要地拒绝大多数或所有人们想要用来编译您的代码的编译器。

一种实用的解决方案是使用第三方 Boost.Config 库,该库维护 a bunch of feature test macrosBoost.Config 的维护人员会跟踪哪些编译器支持哪些功能,并针对每个 Boost.Config 版本更新相应的宏。

(有关 Boost 的内容基于来自 early, now-deleted answer@James McNellis

今天

C++11

今天,there's a version of every major compiler that supports the whole C++11 standard。 .

如果您的代码需要任何 C++11,那么现在要求编译器支持所有 C++11 是合理的。因此,使用 #if __cplusplus >= 201103L。 (See @Paulo M's answer for a standards reference for this macro。) 但要注意有 complications with MSVC——见 @Donald Duck's answer

超越

从 C++20 开始,除了粗粒度的 __cplusplus 宏,还可以通过 #include <version> 得到 a bunch of feature test macros。这基本上是 Boost.Config 的基于标准的替代方案。

根据 this answer from Jarryd 的说法,这些宏实际上至少在某些 2016 时代的 C++14 编译器中可用。

答案 10 :(得分:1)

当您检查C ++ 11库可用性(不是语言功能)时,例如<array>标题,您可以#if __has_include(<array>)

有时检查#if __cplusplus >= 201103L会告诉您使用C ++ 11但是其他设置(如Xcode中的标准库版本设置)可能仍然没有新库可用(大多数可用不同的名称,即{ {1}})