cppreference 在“Predefined macros”部分中包含有关__cplusplus 宏标准值的信息。目前的标准值为:
199711L(C++98 或 C++03)
201103L(C++11)
201402L(C++14)
201703L (C++17)
202002L (C++20)
在最终标准发布之前,任何给定版本的宏值都不会确定。因此,截至 2019 年 6 月,无法知道 C++2a 的宏值是多少(截至 2021 年 2 月,无法知道 C++2b 的宏值是多少)。
库供应商通常在#if __cplusplus > 201703L 上将他们的“C++2a”功能门控,在__cplusplus > 202002L 上门控他们的“C++2b”功能,等等。
具有“C++2a”模式的编译器供应商只需为 __cplusplus 选择任意值,这会使库供应商的检查满意:
GCC(8.x 到 10.x)-std=c++2a 模式使用 __cplusplus == 201709L。
Clang(5.x 到 9.x)-std=c++2a 模式使用 __cplusplus == 201707L。
Microsoft Visual Studio(19.20 到 19.28)/std:c++latest 模式使用 __cplusplus == 201705L if and only if you pass /Zc:__cplusplus!否则它使用199711L。所以要小心!
过去是如何处理转换的?:
Clang 4.0.1 -std=c++1z 设置 __cplusplus == 201406L。 Clang 5.0.0 引入了-std=c++17 和-std=c++2a,使-std=c++1z 成为-std=c++17 的同义词,并将宏(无论您使用了17/1z 中的哪一个)提升到标准值201703L . Clang 10.0 引入了-std=c++20,使-std=c++2a 成为-std=c++20 的同义词,并将宏提升到标准值202002L。截至 2021 年 2 月,Clang 没有正式的“C++2b”模式。
GCC 5.1 引入了-std=c++1z 和-std=c++17 作为同义词,设置__cplusplus == 201500L。 GCC 7.1 将值(无论您使用哪种拼写)提高到标准值201703L。 GCC 8.1 引入了-std=c++2a 和__cplusplus == 201709L。 GCC 10.1 引入了-std=c++20 作为-std=c++2a 的同义词(但将宏保留在201709L)。截至 2021 年 2 月,GCC 中继引入了-std=c++2b 和__cplusplus == 202100L。
奇怪的是,根据 Godbolt Compiler Explorer 的说法,MSVC 在 MSVC 19.16 和 19.20 之间的某个时间将 -std:c++latest 模式的宏从 201704L 提升到了 201705L。截至2021年2月,据我所知,MSVC没有正式的“C++20”模式。