如何确定编译器使用的C++标准的版本?

jas*_*ine 95 c++ standards

如何确定编译器实现的C++标准版本?据我所知,以下是我所知道的标准:

  • C++ 03
  • C++ 98

pmr*_*pmr 212

来自Bjarne Stroustrup C++ 0x FAQ:

__cplusplus

在C++ 0x中,宏__cplusplus将被设置为与当前值不同(大于)的值199711L.

虽然这不像人们想的那样有用.gcc(显然将近10年)将这个值设置为1,排除了一个主要的编译器,直到gcc 4.7.0出现时它被修复.

这些是C++标准以及您应该期望的价值__cplusplus:

  • C++ pre-C++ 98:__cplusplus1.
  • C++ 98:__cplusplus199711L.
  • C++ 98 + TR1:这读作C++ 98,没有办法检查我知道的.
  • C++ 11:__cplusplus201103L.
  • C++ 14:__cplusplus201402L.
  • C++ 17:__cplusplus201703L.

如果编译器可能是较旧的gcc,我们需要求助于编译器特定的hackery(查看版本宏,将其与具有已实现功能的表进行比较)或使用Boost.Config(提供相关的宏).这样做的好处是我们实际上可以选择新标准的特定功能,并在缺少该功能时编写解决方法.这通常比批发解决方案更受欢迎,因为一些编译器会声称实现C++ 11,但只提供一部分功能.

Stdcxx Wiki提供了一个全面的矩阵,用于编译器支持C++ 0x功能(如果您敢于自己检查功能).

遗憾的是,对功能进行更细粒度的检查(例如单个库函数std::copy_if)只能在应用程序的构建系统中完成(运行具有该功能的代码,检查它是否已编译并生成正确的结果)autoconf是选择的工具这条路线).

  • @AlMamun Microsoft仅在VS 15.7中部分修复了`__cplusplus`.查看他们的[Visual C++团队博客](https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus) (5认同)
  • vs2017 给出 __cplusplus 的值 199711 (3认同)
  • @prnr:这可能是真的,但是由提出问题的用户决定接受哪个答案.在当前标记为已接受的答案被发布时,它是正确的,因此原始海报接受了它.该用户可以决定更改已接受的答案,但他们可能不再在该网站上处于活动状态.请参阅:http://meta.stackexchange.com/questions/120568/is-it-possible-to-change-the-chosen-answer (2认同)
  • 常见问题的链接已损坏。 (2认同)

小智 17

请运行以下代码以检查版本.

#include<iostream>

int main() {
    if (__cplusplus == 201703L) std::cout << "C++17\n";
    else if (__cplusplus == 201402L) std::cout << "C++14\n";
    else if (__cplusplus == 201103L) std::cout << "C++11\n";
    else if (__cplusplus == 199711L) std::cout << "C++98\n";
    else std::cout << "pre-standard C++\n";
}
Run Code Online (Sandbox Code Playgroud)

  • 这很有趣,因为在视觉工作室中__cplusplus的值为199711L,而您发布的代码返回了c ++ 98,但是,我使用了c ++ 14的功能,包括变量模板和decltype(auto)。是否可能实施了错误的宏版本? (6认同)
  • 请参阅:https://devblogs.microsoft.com/cppblog/msvc-now- Correctly-reports-__cplusplus/(TLDR:指定标志“/Zc:__cplusplus”) (2认同)
  • 找到它:https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2017#to-set-this-compiler-option-in-visual-studio (2认同)

RED*_*AIR 11

据我所知,没有全面的方法来做到这一点.如果你看一下跨平台/多个编译器支持库的头文件,你总会发现很多使用编译器特定结构来定义这些东西的定义:

/*Define Microsoft Visual C++ .NET (32-bit) compiler */
#if (defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER >= 1300)
     ...
#endif

/*Define Borland 5.0 C++ (16-bit) compiler */
#if defined(__BORLANDC__) && !defined(__WIN32__)
     ...
#endif
Run Code Online (Sandbox Code Playgroud)

您可能必须自己为您使用的所有编译器执行此类定义.


Bjö*_*lex 6

根据您想要实现的目标,Boost.Config可能会对您有所帮助.它不提供标准版本的检测,但它提供了允许您检查特定语言/编译器功能支持的宏.

  • 无论如何,检查功能可能比检查标准版本更好.很少有编译器支持标准的*所有*,但如果它们都支持您需要的有限数量的功能,那么来自给定标准的其余功能是否实现并且正常工作并不重要. (3认同)

Vin*_*enz 5

__cplusplus

在 C++0x 中,宏 __cplusplus 将被设置为一个不同于(大于)当前 199711L 的值。

BS 的 C++0x 常见问题解答


Tar*_*aro 5

通常你应该使用__cplusplus定义来检测 c++17,但默认情况下微软编译器没有正确定义该宏,请参阅https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - 你需要修改项目设置以包含/Zc:__cplusplus开关,或者您可以使用如下语法:

#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
     //C++17 specific stuff here
#endif
Run Code Online (Sandbox Code Playgroud)