有没有办法在编译时检测编译器是否支持C++ 11的某些功能?例如,这样的事情:如何检查C++ 11支持?
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
有没有办法在编译时检测编译器是否支持C++ 11的某些功能?例如,这样的事情:如何检查C++ 11支持?
#ifndef VARIADIC_TEMPLATES_SUPPORTED
#error "Your compiler doesn't support variadic templates. :("
#else
template <typename... DatatypeList>
class Tuple
{
// ...
}
#endif
Boost.Config具有a plethora of macros可用于测试针对特定C++ 11功能的支持。
*他们*如何工作?还是仅仅是典型的Boost黑魔法? – Maxpm 2011-02-19 04:11:31
@Maxpm:在大多数情况下,Boost的维护人员只是跟踪哪些编译器支持哪些功能并更新每个版本的宏。检测你正在编译的编译器很容易。这真的不是什么令人兴奋的事情:真正需要时间才能把谁支持什么的清单放在一起。 – 2011-02-19 04:13:06
在传统的Linux/Unix世界中,autoconf传统上用于测试库和编译器功能以及将它们放入config.h中的错误,这些错误将根据需要用于文件中。
是的autoconf可以用来测试功能,但是它必须让它为失败或成功生成适当的宏,然后才能通过上面的代码来测试。所以这个答案本身并没有增加任何信息。 – 2011-02-19 03:26:18
@LokiAstari:这不是autoconf的工作原理。 Autoconf提供的宏可以让你的配置脚本编译一个测试源文件,并根据编译的成功将#define设置为0或1。 diverscuba23的答案提供了信息,指出OP正在为达到解决真正问题的次优解决方案。 – 2011-12-18 02:44:24
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
有一个名为__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线程和标准的其他特定部分。
C++ 11将`__cplusplus`的值设置为`201103L`。这表明完全符合2011年标准;它没有告诉你有关部分一致性或编译器扩展。如果`__cplusplus`被设置为`201103L`,那么编译器完全符合或对你说谎。如果不是,那么你无法确定它支持哪些功能。 – 2013-05-16 17:24:57
我刚写了一个小测试套件来检查特定编译器支持哪些C++ 11功能。但是,这当然是一个“预编译时间”检查。
如果你不想使用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
提供作为由C++ 11标准(§iso.16.8)表示:
名称__cplusplus定义为值201103L当编译一个C++翻译单元的 。
使用该宏的值,可以检查编译器是否符合C++ 11。现在,如果您正在寻找一种标准方法来检查编译器是否支持C++ 11功能的任何子集,我认为没有标准的可移植方法;您可以检查编译器文档或std库头文件以获取更多信息。
用于检查支持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;
}
我知道这是一个非常古老的问题,但这个问题可能经常被看到,而且答案有点过时。
具有C++ 14标准的较新编译器具有检查功能(包括C++ 11功能)的标准方法。全面的页面是https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
总之,每个功能都有一个标准的宏定义,你可以检查#ifdef
。例如,要检查是否有用户定义的文字,你可以使用
#ifdef __cpp_user_defined_literals
您可以使用此:
#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)。
当您的支票用于C++ 11库可用性(不是语言功能)时,例如<array>
标题,您可以#if __has_include(<array>)
。
有时检查#if __cplusplus >= 201103L
会告诉你,你用C++ 11,但其他设置,如在Xcode标准库版本设置可能仍无法提供的新库(在不同的名字大部分都是可用的,即<tr1/array>
)
你可以有一个名为“assert_variadic_template_support.hpp”的头文件,你可以包含这个头文件,并且可以像`template struct compiler_must_support_variadic_templates;`这样做。语法错误会很快显示出问题。 (就像旁边一样,正确的错误信息要好得多。) –
GManNickG
2011-02-19 00:53:59
解决此问题的“正确”方法是配置测试。 – 2011-12-18 02:40:59