如何检查C++ 11支持?

Max*_*xpm 99 c++ c++11

有没有办法在编译时检测编译器是否支持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线程和标准的其他特定部分的支持.

  • C++ 11将`__cplusplus`的值设置为`201103L`.声称完全符合2011年标准; 它没有告诉你部分一致性或编译器扩展.如果`__cplusplus`设置为`201103L`,那么编译器完全符合或者它对你说谎.如果不是,那么你无法确定它支持哪些功能. (35认同)
  • @DonaldDuck:严格来说,不,他们没有.将`__cplusplus`设置为`199711L`的编译器不是符合标准的C++ 11编译器.他们可能有选择让他们正确行事. (3认同)

Jam*_*lis 51

Boost.Config许多宏可用于测试对特定C++ 11功能的支持.

  • 他们*如何工作?或者它只是典型的Boost黑魔法? (9认同)
  • @Maxpm:在大多数情况下,Boost的维护者只是跟踪哪些编译器支持哪些功能并更新每个版本的宏.检测您正在编译的编译器非常容易.真的没有什么令人兴奋的事情:只需要时间来整理谁支持什么的清单. (9认同)

Pao*_*o M 38

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

编译C++转换单元时,名称__cplusplus被定义为值201103L.

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

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

  • 例如,VS2010和所有c ++ 11编译器都支持static_assert.因此,如果您检查__cplusplus的值大于或等于VS2010中设置的值(即> = 199711L),您可以没问题. (2认同)

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)

  • 我不知道。我认为这个简单的功能来晚了,但仍然非常有用,尤其是 `__has_include()` 宏。 (2认同)

小智 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,看这个答案).

  • 这个答案是不正确的。对于带有 GCC 4.8 的 `g++ -std=c++98`,它错误地打印了 `C++11 is supported`。 (2认同)

小智 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编译器的完整版本列表


div*_*a23 6

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

  • @LokiAstari:这不是autoconf的工作方式.Autoconf提供的宏可让您使用configure脚本编译测试源文件,并根据编译的成功将#define设置为0或1.diverscuba23的答案通过指出OP正在寻找针对真实问题的次优解决方案来提供信息. (3认同)
  • 是的autoconf可以用来测试功能,但是你必须让它为失败或成功生成适当的宏,然后可以通过上面的代码进行测试.所以这个答案本身没有添加任何信息. (2认同)

Max*_*xpm 4

快速历史记录

\n

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

\n

如果您的代码依赖于 C++11 功能的子集,则您没有标准方法来询问编译器是否专门支持它们。

\n

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

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

一个实用的解决方案是使用第三方Boost.Config库,该库维护了一堆功能测试宏Boost.Config\ 的维护人员跟踪哪些编译器支持哪些功能,并相应地为每个Boost.Config版本更新宏。

\n

(有关 Boost 的内容基于@James McNellis早期答案,现已删除

\n

今天

\n

C++11

\n

如今,每个主要编译器都有一个支持整个 C++11 标准的版本。。

\n

如果您的代码需要任何C++11,那么现在要求编译器支持所有C++11 是合理的。所以,使用#if __cplusplus >= 201103L. (有关此宏的标准参考,请参阅 @Paulo M\ 的答案。)但请注意MSVC \xe2\x80\x94存在复杂性,请参阅 @Donald Duck\ 的答案

\n

超过

\n

从C++20开始,除了粗粒度的__cplusplus宏之外,你还可以#include <version>得到一堆特性测试宏。这基本上是基于标准的替代方案Boost.Config

\n

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

\n