2011-02-19 81 views
80

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

#ifndef VARIADIC_TEMPLATES_SUPPORTED 

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

#else 

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

#endif 
+2

你可以有一个名为“assert_variadic_template_support.hpp”的头文件,你可以包含这个头文件,并且可以像`template struct compiler_must_support_variadic_templates;`这样做。语法错误会很快显示出问题。 (就像旁边一样,正确的错误信息要好得多。) – GManNickG 2011-02-19 00:53:59

+0

解决此问题的“正确”方法是配置测试。 – 2011-12-18 02:40:59

回答

52

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

+6

*他们*如何工作?还是仅仅是典型的Boost黑魔法? – Maxpm 2011-02-19 04:11:31

+7

@Maxpm:在大多数情况下,Boost的维护人员只是跟踪哪些编译器支持哪些功能并更新每个版本的宏。检测你正在编译的编译器很容易。这真的不是什么令人兴奋的事情:真正需要时间才能把谁支持什么的清单放在一起。 – 2011-02-19 04:13:06

5

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

+2

是的autoconf可以用来测试功能,但是它必须让它为失败或成功生成适当的宏,然后才能通过上面的代码来测试。所以这个答案本身并没有增加任何信息。 – 2011-02-19 03:26:18

+2

@LokiAstari:这不是autoconf的工作原理。 Autoconf提供的宏可以让你的配置脚本编译一个测试源文件,并根据编译的成功将#define设置为0或1。 diverscuba23的答案提供了信息,指出OP正在为达到解决真正问题的次优解决方案。 – 2011-12-18 02:44:24

+1

http://stackoverflow.com/q/11909347/580412 https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html – phs 2015-08-27 00:56:30

94

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

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

它被设置为199711L在Visual Studio 2010 SP1,但我不知道,如果厂商会如果他们只具有(部分)编译器级别的支持,而不是具有所有C++ 11更改的标准C++库,就可以大胆地增加它。

So Boost在另一个答案中提到的定义仍然是找出是否存在唯一理智的方法,例如,支持C++ 11线程和标准的其他特定部分。

+26

C++ 11将`__cplusplus`的值设置为`201103L`。这表明完全符合2011年标准;它没有告诉你有关部分一致性或编译器扩展。如果`__cplusplus`被设置为`201103L`,那么编译器完全符合或对你说谎。如果不是,那么你无法确定它支持哪些功能。 – 2013-05-16 17:24:57

16

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

https://github.com/sloede/cxx11tests

7

如果你不想使用Boost.Config和需要测试支持C++ 11然后检查不断__cplusplus的价值会做的编译器。但是,编译器可能支持C++ 11标准的大多数流行功能,但它不支持整个规范。如果您想启用特定的Visual Studio编译器在尚未100%兼容C++ 11级的规格,然后使用下面的代码片段,其允许在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 

版本的完整列表的用于Visual Studio编译器在How to Detect if I'm Compiling Code With Visual Studio 2008

27

提供作为由C++ 11标准(§iso.16.8)表示:

名称__cplusplus定义为值201103L当编译一个C++翻译单元的 。

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

16

用于检查支持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; 
} 
20

我知道这是一个非常古老的问题,但这个问题可能经常被看到,而且答案有点过时。

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

总之,每个功能都有一个标准的宏定义,你可以检查#ifdef。例如,要检查是否有用户定义的文字,你可以使用

#ifdef __cpp_user_defined_literals 
6

您可以使用此:

#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之前的其他编译器的值。此代码将_cplusplus宏与201103L比较,用于除Visual Studio以外的所有编译器,并且如果编译器是Visual Studio,它将检查Visual Studio的版本是否晚于2015,这是完全支持C++ 11的第一版Visual Studio(对于Visual Studio 2015,_MSC_VER宏的值为1900,请参阅this answer)。

1

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

有时检查#if __cplusplus >= 201103L会告诉你,你用C++ 11,但其他设置,如在Xcode标准库版本设置可能仍无法提供的新库(在不同的名字大部分都是可用的,即<tr1/array>