跳到主要内容

功能测试 (自 C++20 起)

标准定义了一组 预处理器宏,对应于 C++ 语言和库在 C++更高版本中引入的功能。它们旨在作为一种简单且可移植的方式来检测这些功能的可用性。

属性

pub__has_cpp_attribute( attribute-token )

检查对由 attribute-token (宏展开后)命名的 属性的支持。

对于标准属性,它会扩展到属性添加到工作草案的年和月 (见下表),而供应商特定属性的存在则由非零值确定。

__has_cpp_attribute 可以在 #if#elif 的表达式中展开。它被 #ifdef#ifndef、 #elifdef#elifndef (C++23 起)defined 作为已定义宏处理,但不能用于其他任何地方。

attribute-token属性标准论文(s)
assume[[assume]]202207L(C++23)P1774R8
carries_dependency[[carries_dependency]]200809L(C++11)N2556, N2643
deprecated[[deprecated]]201309L(C++14)N3760
fallthrough[[fallthrough]]201603L(C++17)P0188R1
likely[[likely]]201803L(C++20)P0479R5
maybe_unused[[maybe_unused]]201603L(C++17)P0212R1
no_unique_address[[no_unique_address]]201803L(C++20)P0840R2
nodiscard[[nodiscard]]201603L
201907L
(C++17)
(C++20)
P0189R1
P1301R4
noreturn[[noreturn]]200809L(C++11)N2761
unlikely[[unlikely]]201803L(C++20)P0479R5

语言特性

以下宏在每个翻译单元中都预定义了。每个宏都扩展为一个整数文字,表示相应的特性在工作草案中包含的年和月。

当特性发生重大变化时,宏会相应更新。

宏名称特性标准论文(s)
__cpp_aggregate_bases带有基类的 聚合类201603L(C++17)P0017R1
__cpp_aggregate_nsdmi带有 成员默认初始化器聚合类201304L(C++14)N3653
__cpp_aggregate_paren_init直接初始化 形式的 聚合初始化201902L(C++20)P0960R3
__cpp_alias_templates别名模板200704L(C++11)N2258
__cpp_aligned_new面向过对齐数据的动态内存分配201606L(C++17)P0035R4
__cpp_attributes属性200809L(C++11)N2761
__cpp_auto_castauto(x)auto{x}202110L(C++23)P0849R8
__cpp_binary_literals二进制字面量201304L(C++14)N3472
__cpp_capture_star_thisLambda 捕获 *this 按值方式表示为 [=,*this]201603L(C++17)P0018R3
__cpp_char8_tchar8_t201811L(C++20)P0482R6
__cpp_char8_tchar8_t 兼容性和可移植性修复 ( 允许从 UTF-8 字符串字面量 初始化 (无符号) char 数组)202207L(C++20)(DR)P2513R4
__cpp_concepts概念201907L(C++20)P0734R0
P1084R2
P1452R2
__cpp_concepts条件化的平凡特殊成员函数202002L(C++20)P0848R3
P2493R0
__cpp_conditional_explicitexplicit(bool)201806L(C++20)P0892R2
__cpp_consteval立即函数201811L(C++20)P1073R3
__cpp_consteval使 consteval 能够向上传播202211L(C++20)(DR)P2564R3
__cpp_constexprconstexpr200704L(C++11)N2235
__cpp_constexpr宽松的 constexpr非 const 的 constexpr 成员函数201304L(C++14)N3652
__cpp_constexprConstexpr lambda201603L(C++17)P0170R1
__cpp_constexpr常量表达式中的 虚函数 调用201806L(C++20)P1064R0
__cpp_constexpr常量表达式中的 try-catch 块、dynamic_cast 和多态 typeid201811L(C++20)P1002R1
P1327R1
__cpp_constexpr常量表达式函数中的平凡 默认初始化asm 声明201907L(C++20)P1331R2
P1668R1
__cpp_constexpr常量求值中更改联合体的活动成员202002L(C++20)P1330R0
__cpp_constexpr常量表达式函数中的非字面量变量、标签和 goto 语句202110L(C++23)P2242R3
__cpp_constexpr放宽对 constexpr 函数和函数模板的某些限制202207L(C++23)P2448R2
__cpp_constexpr允许在 constexpr 函数中使用静态 constexpr 变量202211L(C++23)P2647R1
__cpp_constexpr_dynamic_alloc常量表达式函数中的动态存储期操作201907L(C++20)P0784R7
__cpp_constexpr_in_decltype在需要常量求值时生成函数和变量定义201711L(C++11)(DR)P0859R0
__cpp_constinitconstinit201907L(C++20)P1143R2
__cpp_decltypedecltype200707L(C++11)N2343
__cpp_decltype_auto普通函数的返回类型推导201304L(C++14)N3638
__cpp_deduction_guides类模板的模板参数推导201703L(C++17)P0091R3
P0512R0
P0620R0
__cpp_deduction_guides聚合体和别名的 CTAD201907L(C++20)P1814R0
P1816R0
__cpp_delegating_constructors委托构造函数200604L(C++11)N1986
__cpp_designated_initializers指定初始化器201707L(C++20)P0329R4
__cpp_enumerator_attributes枚举数的属性201411L(C++17)N4266
__cpp_explicit_this_parameter显式对象参数202110L(C++23)P0847R7
__cpp_fold_expressions折叠表达式201603L(C++17)N4295
P0036R0
__cpp_generic_lambdas泛型 lambda 表达式201304L(C++14)N3649
__cpp_generic_lambdas泛型 lambda 的显式模板参数列表201707L(C++20)P0428R2
__cpp_guaranteed_copy_elision通过简化的 值类别 实现保证的复制省略201606L(C++17)P0135R1
__cpp_hex_float十六进制浮点文字量201603L(C++17)P0245R1
__cpp_if_constevalconsteval if202106L(C++23)P1938R3
__cpp_if_constexprconstexpr if201606L(C++17)P0292R2
__cpp_impl_coroutine协程 (编译器支持)201902L(C++20)P0912R5
LWG3393
__cpp_impl_destroying_delete销毁 new 运算符 (编译器支持)201806L(C++20)P0722R3
__cpp_impl_three_way_comparison三向比较 (编译器支持)201907L(C++20)P0515R3
P0768R1
P1185R2
P1630R1
__cpp_implicit_move更简单的 隐式移动202207L(C++23)P2266R3
__cpp_inheriting_constructors继承构造函数200802L(C++11)N2540
__cpp_inheriting_constructors继承构造函数的措辞修改201511L(C++11)(DR)P0136R1
__cpp_init_capturesLambda 初始化捕获201304L(C++14)N3648
__cpp_init_captures允许在 Lambda 初始化捕获中使用包展开201803L(C++20)P0780R2
__cpp_initializer_lists列表初始化std::initializer_list200806L(C++11)N2672
__cpp_inline_variables内联变量201606L(C++17)P0386R2
__cpp_lambdasLambda 表达式200907L(C++11)N2927
__cpp_modules模块201907L(C++20)P1103R3
P1811R0
__cpp_multidimensional_subscript多维 下标运算符202110L(C++23)P2128R6
__cpp_multidimensional_subscriptstatic operator[]202211L(C++23)P2589R1
__cpp_named_character_escapes命名 通用字符转义202207L(C++23)P2071R2
__cpp_namespace_attributes命名空间的属性201411L(C++17)N4266
__cpp_noexcept_function_type异常规范 纳入类型系统201510L(C++17)P0012R1
__cpp_nontype_template_args允许对所有 非类型模板参数 进行常量求值201411L(C++17)N4268
__cpp_nontype_template_args类类型和浮点类型作为 非类型模板参数201911L(C++20)P1907R1
__cpp_nontype_template_parameter_auto使用 auto 声明 非类型模板参数201606L(C++17)P0127R2
__cpp_nsdmi非静态数据成员初始化器200809L(C++11)N2756
__cpp_range_based_for基于范围的 for 循环200907L(C++11)N2930
__cpp_range_based_for带有不同 begin/end 类型的 基于范围的 for 循环201603L(C++17)P0184R0
__cpp_range_based_for基于范围的 for 循环中的生命周期扩展202211L(C++23)P2718R0
__cpp_raw_strings原始字符串字面量200710L(C++11)N2442
__cpp_ref_qualifiers引用限定符200710L(C++11)N2439
__cpp_return_type_deduction普通函数的返回类型推导201304L(C++14)N3638
__cpp_rvalue_references右值引用200610L(C++11)N2118
__cpp_size_t_suffixsize_t 及其有符号版本的字面量后缀202011L(C++23)P0330R8
__cpp_sized_deallocation带尺寸的 deallocation201309L(C++14)N3778
__cpp_static_assertstatic_assert200410L(C++11)N1720
__cpp_static_assert单参数 static_assert201411L(C++17)N3928
__cpp_static_call_operatorstatic operator()202207L(C++23)P1169R4
__cpp_structured_bindings结构化绑定201606L(C++17)P0217R3
__cpp_template_template_args匹配 模板模板参数201611L(C++17)P0522R0
__cpp_threadsafe_static_init带并发的动态初始化和销毁200806L(C++11)N2660
__cpp_unicode_characters新的字符类型 (char16_tchar32_t)200704L(C++11)N2249
__cpp_unicode_literalsUnicode 字符串字面量200710L(C++11)N2442
__cpp_user_defined_literals用户定义字面量200809L(C++11)N2765
__cpp_using_enumusing enum201907L(C++20)P1099R5
__cpp_variable_templates变量模板201304L(C++14)N3651
__cpp_variadic_templates可变参数模板200704L(C++11)N2242
__cpp_variadic_usingusing 声明 中使用包展开201611L(C++17)P0195R2

库特性

如果包含了 <version> 头文件或下表中任何相应的头文件,则定义以下宏。每个宏都扩展为一个整数文字,表示相应的特性在工作草案中包含的年和月。

当特性发生重大变化时,宏会相应更新。

宏名称特性头文件标准论文(s)
__cpp_lib_adaptor_iterator_pair_constructor用于 std::stack 和 std::queue 的适配器迭代器对构造函数202106L<queue> <stack>(C++23)P1425R4
__cpp_lib_addressof_constexprConstexpr std::addressof201603L<memory>(C++17)LWG2296
__cpp_lib_algorithm_iterator_requirementsRanges 迭代器作为非 Ranges 算法 的输入202207L<algorithm> <memory> <numeric>(C++23)P2408R5
__cpp_lib_allocate_at_least分配器接口中的大小反馈,例如:std::allocator::allocate_at_least, std::allocator_traits::allocate_at_least202302L<memory>(C++23)P0401R6 P2652R2
__cpp_lib_allocator_traits_is_always_equalstd::allocator_traits::is_always_equal201411L<memory> <scoped_allocator> <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set>(C++17)N4258
__cpp_lib_anystd::any201606L<any>(C++17)P0220R1 P0032R3
__cpp_lib_applystd::apply201603L<tuple>(C++17)P0220R1
__cpp_lib_array_constexprstd::reverse_iterator、std::move_iterator、std::array 和 范围访问 的 Constexpr201603L<iterator> <array>(C++17)P0031R0
__cpp_lib_array_constexprConstexprIterator; std::array 的常量表达式比较;杂项常量表达式部分 (std::array::fill 等)201811L<iterator> <array>(C++20)P0858R0 LWG3257 P1023R0 P1032R1
__cpp_lib_as_conststd::as_const201510L<utility>(C++17)P0007R1
__cpp_lib_associative_heterogeneous_erasure关联容器无序关联容器 中进行异构擦除202110L<map> <set> <unordered_map> <unordered_set>(C++23)P2077R3
__cpp_lib_assume_alignedstd::assume_aligned201811L<memory>(C++20)P1007R3
__cpp_lib_atomic_flag_teststd::atomic_flag::test201907L<atomic>(C++20)P1135R6
__cpp_lib_atomic_float浮点原子类型201711L<atomic>(C++20)P0020R6
__cpp_lib_atomic_is_always_lock_freeconstexpr atomic<T>::is_always_lock_free201603L<atomic>(C++17)P0152R1
__cpp_lib_atomic_lock_free_type_aliases原子无锁整数类型 (std::atomic_signed_lock_free, std::atomic_unsigned_lock_free)201907L<atomic>(C++20)P1135R6
__cpp_lib_atomic_refstd::atomic_ref201806L<atomic>(C++20)P0019R8
__cpp_lib_atomic_shared_ptrstd::atomic<std::shared_ptr>201711L<memory>(C++20)P0718R2
__cpp_lib_atomic_value_initialization修复原子初始化 (默认值初始化 std::atomic)201911L<atomic> <memory>(C++20)P0883R2
__cpp_lib_atomic_wait高效的 std::atomic 等待201907L<atomic>(C++20)P1135R6
__cpp_lib_barrierstd::barrier201907L<barrier>(C++20)P1135R6
__cpp_lib_barrierstd::barrier 的阶段完成保证202302L<barrier>(C++23)P2588R3
__cpp_lib_bind_backstd::bind_back202202L<functional>(C++23)P2387R3
__cpp_lib_bind_frontstd::bind_front201907L<functional>(C++20)P0356R5 P1651R0
__cpp_lib_bit_caststd::bit_cast201806L<bit>(C++20)P0476R2
__cpp_lib_bitops位运算201907L<bit>(C++20)P0553R4
__cpp_lib_bool_constantstd::bool_constant201505L<type_traits>(C++17)N4389
__cpp_lib_bounded_array_traitsstd::is_bounded_array, std::is_unbounded_array201902L<type_traits>(C++20)P1357R1
__cpp_lib_boyer_moore_searcher搜索器201603L<functional>(C++17)P0220R1
__cpp_lib_bytestd::byte201603L<cstddef>(C++17)P0298R3
__cpp_lib_byteswapstd::byteswap202110L<bit>(C++23)P1272R4
__cpp_lib_char8_t对 char8_t 的库支持201907L<atomic> <filesysti> <istream> <limits> <locale> <ostream> <string> <string_view>(C++20)P0482R6 P1423R3
__cpp_lib_chronostd::chrono::duration 和 std::chrono::time_point 的舍入函数201510L<chrono>(C++17)P0092R1
__cpp_lib_chronostd::chrono::duration 和 std::chrono::time_point 所有成员函数的 Constexpr201611L<chrono>(C++17)P0505R0
__cpp_lib_chrono日历时区201907L<chrono>(C++20)P0355R7 P1466R3
__cpp_lib_chrono_udls时间类型的用户定义字面量201304L<chrono>(C++14)N3642
__cpp_lib_clampstd::clamp201603L<algorithm>(C++17)P0025R0
__cpp_lib_common_reference使 std::common_reference_t of std::reference_wrapper 成为引用类型202302L<type_traits>(C++23)P2655R3
__cpp_lib_common_reference_wrapper使 std::common_reference_t of std::reference_wrapper 成为引用类型202302L<functional>(C++23)P2655R3
__cpp_lib_complex_udlsstd::complex 的用户定义字面量201309L<complex>(C++14)N3779
__cpp_lib_concepts标准库概念202002L<concepts>(C++20)P0898R3 P1754R1 P1964R2
__cpp_lib_concepts用于 equality_comparable_with、totally_ordered_with 和 three_way_comparable_with 的仅移动类型202207L<compare> <concepts>(C++23)P2404R3
__cpp_lib_constexpr_algorithms算法的 Constexpr201806L<algorithm>(C++20)P0202R3 P0879R0 LWG3256
__cpp_lib_constexpr_bitset更 constexpr 的 std::bitset202207L<bitset>(C++23)P2417R2
__cpp_lib_constexpr_charconv为整数类型添加 to_chars 和 from_chars 函数的 constexpr 修饰符202207L<charconv>(C++23)P2291R3
__cpp_lib_constexpr_cmath<cmath> 和 <cstdlib> 中的数学函数的 Constexpr202202L<cmath> <cstdlib>(C++23)P0533R9
__cpp_lib_constexpr_complexstd::complex 的 Constexpr201711L<complex>(C++20)P0415R1
__cpp_lib_constexpr_dynamic_allocstd::allocator 和相关工具的 Constexpr201907L<memory>(C++20)P0784R7
__cpp_lib_constexpr_functional杂项 constexpr 部分 (std::default_searcher);constexpr INVOKE201907L<functional>(C++20)P1032R1 P1065R2
__cpp_lib_constexpr_iterator杂项 constexpr 部分 (std::insert_iterator 等)201811L<iterator>(C++20)P1032R1
__cpp_lib_constexpr_memorystd::pointer_traits 中的 Constexpr201811L<memory>(C++20)P1006R1
__cpp_lib_constexpr_memoryConstexpr std::unique_ptr202202L<memory>(C++23)P2273R3
__cpp_lib_constexpr_numeric<numeric> 中 算法 的 Constexpr201911L<numeric>(C++20)P1645R1
__cpp_lib_constexpr_stringstd::string 的 Constexpr201907L<string>(C++20)P0426R1 P1032R1 P0980R1
__cpp_lib_constexpr_string_view杂项 constexpr 部分 (std::string_view::copy)201811L<string_view>(C++20)P0426R1 P1032R1
__cpp_lib_constexpr_tuple杂项 constexpr 部分 (std::tuple::operator= 等)201811L<tuple>(C++20)P1032R1
__cpp_lib_constexpr_typeinfostd::type_info::operator== 的 Constexpr202106L<typeinfo>(C++23)P1328R1
__cpp_lib_constexpr_utility杂项 constexpr 部分 (std::pair::operator= 等)201811L<utility>(C++20)P1032R1
__cpp_lib_constexpr_vectorstd::vector 的 Constexpr201907L<vector>(C++20)P1004R2
__cpp_lib_containers_ranges容器和字符串的 感知 Ranges 的构造和插入202202L<vector> <list> <forward_list > <map> <set> <unordered_map> <unordered_set> <deque> <queue> <stack> <string>(C++23)P1206R7
__cpp_lib_coroutine协程 (库支持)201902L<coroutine>(C++20)P0912R5 LWG3393
__cpp_lib_destroying_delete销毁 new 运算符 (库支持)201806L<new>(C++20)P0722R3
__cpp_lib_enable_shared_from_thisstd::enable_shared_from_this::weak_from_this201603L<memory>(C++17)P0033R1
__cpp_lib_endianstd::endian201907L<bit>(C++20)P0463R1 P1612R1
__cpp_lib_erase_if统一容器擦除202002L<string> <deque> <forward_list > <list> <vector> <map> <set> <unordered_map> <unordered_set>(C++20)P1209R0 P1115R3
__cpp_lib_exchange_functionstd::exchange201304L<utility>(C++14)N3668
__cpp_lib_execution并行策略201603L<execution>(C++17)P0024R2
__cpp_lib_executionstd::execution::unsequenced_policy201902L<execution>(C++20)P1001R2
__cpp_lib_expected类模板 std::expected202202L<expected>(C++23)P0323R12
__cpp_lib_expectedstd::expected 的单子函数202211L<expected>(C++23)P2505R5
__cpp_lib_filesystem文件系统库201703L<filesystem>(C++17)P0218R1 P0219R1 P0392R0 P0317R1
__cpp_lib_flat_mapstd::flat_map 和 std::flat_multimap202207L<flat_map>(C++23)P0429R9
__cpp_lib_flat_setstd::flat_set 和 std::flat_multiset202207L<flat_set>(C++23)P1222R4 LWG3751
__cpp_lib_format文本格式化201907L<format>(C++20)P0645R10 P1361R2 P1652R1
__cpp_lib_format编译时格式字符串检查;减少 std::vformat_to 的参数化202106L<format>(C++20) (DR)P2216R3
__cpp_lib_format修复 chrono 格式化器的区域设置处理;支持非 const 可格式化类型202110L<format>(C++20) (DR)P2372R3 P2418R2
__cpp_lib_format公开 std::basic_format_string;阐明本地化 chrono 类型格式化中的编码处理202207L<format>(C++23)P2419R2 P2508R1
__cpp_lib_format_ranges格式化范围202207L<format>(C++23)P2286R8 P2585R1 LWG3750
__cpp_lib_formatters格式化 std::thread::id 和 std::stacktrace202302L<stacktrace> <thread>(C++23)P2693R1
__cpp_lib_forward_likestd::forward_like202207L<utility>(C++23)P2445R1
__cpp_lib_gcd_lcmstd::gcd, std::lcm201606L<numeric>(C++17)P0295R0
__cpp_lib_generatorstd::generator: 用于范围的同步协程生成器202207L<generator>(C++23)P2502R2
__cpp_lib_generic_associative_lookup关联容器 中进行异构比较查找201304L<map> <set>(C++14)N3657
__cpp_lib_generic_unordered_lookup无序关联容器 中进行异构比较查找201811L<unordered_map> <unordered_set>(C++20)P0919R3
__cpp_lib_hardware_interference_sizeconstexpr std::hardware_interference_size201703L<new>(C++17)P0154R1
__cpp_lib_has_unique_object_representationsstd::has_unique_object_representations201606L<type_traits>(C++17)P0258R2
__cpp_lib_hypot3 参数重载的 std::hypot201603L<cmath>(C++17)P0030R1
__cpp_lib_incomplete_container_elements对 std::forward_list、std::list 和 std::vector 的最小不完整类型支持201505L<forward_list > <list> <vector>(C++17)N4510
__cpp_lib_int_pow2整数幂运算 (std::has_single_bit, std::bit_ceil, std::bit_floor, std::bit_width)202002L<bit>(C++20)P0556R3 P1956R1
__cpp_lib_integer_comparison_functions整数比较函数202002L<utility>(C++20)P0586R2
__cpp_lib_integer_sequence编译时整数序列201304L<utility>(C++14)N3658
__cpp_lib_integral_constant_callablestd::integral_constant::operator()201304L<type_traits>(C++14)N3545
__cpp_lib_interpolatestd::lerp, std::midpoint201902L<cmath> <numeric>(C++20)P0811R3
__cpp_lib_invokestd::invoke201411L<functional>(C++17)N4169
__cpp_lib_invoke_rstd::invoke_r202106L<functional>(C++23)P2136R3
__cpp_lib_ios_noreplace为 fstreams 支持独占模式202207L<ios>(C++23)P2467R1
__cpp_lib_is_aggregatestd::is_aggregate201703L<type_traits>(C++17)LWG2911
__cpp_lib_is_constant_evaluatedstd::is_constant_evaluated201811L<type_traits>(C++20)P0595R2
__cpp_lib_is_finalstd::is_final201402L<type_traits>(C++14)LWG2112
__cpp_lib_is_implicit_lifetimestd::is_implicit_lifetime202302L<type_traits>(C++23)P2674R1
__cpp_lib_is_invocablestd::is_invocable, std::invoke_result201703L<type_traits>(C++17)P0604R0
__cpp_lib_is_layout_compatiblestd::is_layout_compatible201907L<type_traits>(C++20)P0466R5
__cpp_lib_is_nothrow_convertiblestd::is_nothrow_convertible201806L<type_traits>(C++20)P0758R1 LWG3356
__cpp_lib_is_null_pointerstd::is_null_pointer201309L<type_traits>(C++14)LWG2247
__cpp_lib_is_pointer_interconvertible指针互换性特征:std::is_pointer_interconvertible_with_class, std::is_pointer_interconvertible_base_of201907L<type_traits>(C++20)P0466R5
__cpp_lib_is_scoped_enumstd::is_scoped_enum202011L<type_traits>(C++23)P1048R1
__cpp_lib_is_swappablenothrow-swappable 特征201603L<type_traits>(C++17)P0185R1
__cpp_lib_jthread停止令牌joining 线程201911L<stop_token> <thread>(C++20)P0660R10 P1869R1
__cpp_lib_latchstd::latch201907L<latch>(C++20)P1135R6
__cpp_lib_launder核心问题 1776:包含引用成员的类对象的替换 (std::launder)201606L<new>(C++17)P0137R1
__cpp_lib_list_move_return_type更改 std::forward_list 和 std::list 的 move()move_if()unique() 成员的返回类型201806L<forward_list > <list>(C++20)P0646R1
__cpp_lib_logical_traits类型特征的逻辑运算201510L<type_traits>(C++17)P0013R1
__cpp_lib_make_from_tuplestd::make_from_tuple()201606L<tuple>(C++17)P0209R2
__cpp_lib_make_reverse_iteratorstd::make_reverse_iterator201402L<iterator>(C++14)LWG2285
__cpp_lib_make_uniquestd::make_unique201304L<memory>(C++14)N3656
__cpp_lib_map_try_emplacestd::map::try_emplace, std::map::insert_or_assign201411L<map>(C++17)N4279
__cpp_lib_math_constants数学常量201907L<numbers>(C++20)P0631R8
__cpp_lib_math_special_functionsC++17 的数学特殊函数201603L<cmath>(C++17)P0226R1
__cpp_lib_mdspanstd::mdspan202207L<mdspan>(C++23)P0009R18 P2599R2 P2604R0 P2613R1
__cpp_lib_memory_resourcestd::pmr::memory_resource201603L<memory_resource>(C++17)P0220R1
__cpp_lib_modules标准库模块 stdd 和 std.compat202207L(C++23)P2465R3
__cpp_lib_move_iterator_concept使 std::move_iterator<T*> 成为随机访问迭代器202207L<iterator>(C++23)P2520R0
__cpp_lib_move_only_functionstd::move_only_function202110L<functional>(C++23)P0288R9
__cpp_lib_node_extract拼接映射和集合 (std::map::extract, std::map::merge, std::map::insert(node_type) 等)201606L<map> <set> <unordered_map> <unordered_set>(C++17)P0083R3
__cpp_lib_nonmember_container_accessstd::size(), std::data() 和 std::empty()201411L<iterator> <array> <deque> <forward_list > <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector>(C++17)N4280
__cpp_lib_not_fnstd::not_fn()201603L<functional>(C++17)P0005R4
__cpp_lib_null_iterators空 LegacyForwardIterators201304L<iterator>(C++14)N3644
__cpp_lib_optionalstd::optional201606L<optional>(C++17)P0220R1 P0032R3 P0307R2
__cpp_lib_optional完全 constexpr std::optional202106L<optional>(C++20) (DR)P2231R1
__cpp_lib_optionalstd::optional 中的单子操作202110L<optional>(C++23)P0798R8 LWG3621
__cpp_lib_out_ptrstd::out_ptr, std::inout_ptr202106L<memory>(C++23)P1132R7
__cpp_lib_parallel_algorithm并行算法201603L<algorithm> <numeric>(C++17)P0024R2
__cpp_lib_polymorphic_allocatorstd::pmr::polymorphic_allocator<> 作为词汇类型201902L<memory_resource>(C++20)P0339R6 LWG3437
__cpp_lib_print格式化输出202207L<ostream> <print>(C++23)P2093R14
__cpp_lib_quoted_string_iostd::quoted201304L<iomanip>(C++14)N3654
__cpp_lib_rangesRanges 库约束算法201911L<algorithm> <functional> <iterator> <memory> <ranges>(C++20)P0896R4 P1035R7 P1716R3
__cpp_lib_ranges非默认可初始化的视图202106L(C++20) (DR)P2325R3
__cpp_lib_ranges带有所有权的视图202110L(C++20) (DR)P2415R2
__cpp_lib_rangesstd::ranges::range_adaptor_closure202202L(C++23)P2387R3
__cpp_lib_ranges放宽范围适配器以允许仅移动类型202207L(C++23)P2494R2
__cpp_lib_ranges移除 ranges::begin, ranges::end, ranges::rbegin, ranges::rend, 和 ranges::size 中的“毒丸”重载202211L(C++23)P2602R2
__cpp_lib_ranges放宽 ranges 以允许某些投影202302L(C++23)P2609R3
__cpp_lib_ranges_as_conststd::const_iterator, std::ranges::as_const_view202207L<ranges>(C++23)P2278R4
__cpp_lib_ranges_as_rvaluestd::ranges::as_rvalue_view202207L<ranges>(C++23)P2446R2
__cpp_lib_ranges_cartesian_productstd::ranges::cartesian_product_view202207L<ranges>(C++23)P2374R4 P2540R1
__cpp_lib_ranges_chunkstd::ranges::chunk_view202202L<ranges>(C++23)P2442R1
__cpp_lib_ranges_chunk_bystd::ranges::chunk_by_view202202L<ranges>(C++23)P2443R1
__cpp_lib_ranges_containsstd::ranges::contains202207L<algorithm>(C++23)P2302R4
__cpp_lib_ranges_enumeratestd::ranges::enumerate_view202302L<ranges>(C++23)P2164R9
__cpp_lib_ranges_find_laststd::find_last()202207L<algorithm>(C++23)P1223R5
__cpp_lib_ranges_foldstd::ranges fold 算法202207L<algorithm>(C++23)P2322R6
__cpp_lib_ranges_iotastd::ranges::iota202202L<numeric>(C++23)P2440R1
__cpp_lib_ranges_join_withstd::ranges::join_with_view202202L<ranges>(C++23)P2441R2
__cpp_lib_ranges_repeatstd::ranges::repeat_view202207L<ranges>(C++23)P2474R2
__cpp_lib_ranges_slidestd::ranges::slide_view202202L<ranges>(C++23)P2442R1
__cpp_lib_ranges_starts_ends_withstd::ranges::starts_with, std::ranges::ends_with202106L<algorithm>(C++23)P1659R3
__cpp_lib_ranges_stridestd::ranges::stride_view202207L<ranges>(C++23)P1899R3
__cpp_lib_ranges_to_containerstd::ranges::to202202L<ranges>(C++23)P1206R7
__cpp_lib_ranges_zipstd::ranges::zip_view, std::ranges::zip_transform_view, std::ranges::adjacent_view, std::ranges::adjacent_transform_view202110L<ranges> <tuple> <utility>(C++23)P2321R2
__cpp_lib_raw_memory_algorithms扩展内存管理工具201606L<memory>(C++17)P0040R3
__cpp_lib_reference_from_temporarystd::reference_constructs_from_temporary 和 std::reference_converts_from_temporary202202L<type_traits>(C++23)P2255R2
__cpp_lib_move_cvrefstd::move_cvref201711L<type_traits>(C++20)P0550R2
__cpp_lib_result_of_sfinaestd::result_of 和 SFINAE201210L<type_traits> <functional>(C++14)N3462
__cpp_lib_robust_nonmodifying_seq_ops使非修改序列操作更健壮 (std::mismatch、std::equal 和 std::is_permutation 的双范围重载)201304L<algorithm>(C++14)N3671
__cpp_lib_samplestd::sample201603L<algorithm>(C++17)P0220R1
__cpp_lib_scoped_lockstd::scoped_lock201703L<mutex>(C++17)P0156R2
__cpp_lib_semaphorestd::counting_semaphore, std::binary_semaphore201907L<semaphore>(C++20)P1135R6
__cpp_lib_shared_mutexstd::shared_mutex (无计时)201505L<shared_mutex>(C++17)N4508
__cpp_lib_shared_ptr_arraysstd::shared_ptr<T[]>201611L<memory>(C++17)P0497R0
__cpp_lib_shared_ptr_arraysstd::make_shared 的数组支持201707L<memory>(C++20)P0674R1
__cpp_lib_shared_ptr_weak_typeshared_ptr::weak_type201606L<memory>(C++17)P0163R0
__cpp_lib_shared_timed_mutexstd::shared_timed_mutex201402L<shared_mutex>(C++14)N3891
__cpp_lib_shiftstd::shift_left 和 std::shift_right201806L<algorithm>(C++20)P0769R2
__cpp_lib_shiftstd::ranges::shift_left 和 std::ranges::shift_right202202L<algorithm>(C++23)P2440R1
__cpp_lib_smart_ptr_for_overwrite智能指针创建和默认初始化 (std::allocate_shared_for_overwrite, std::make_shared_for_overwrite, std::make_unique_for_overwrite)202002L<memory>(C++20)P1020R1 P1973R1
__cpp_lib_source_location源代码信息捕获 (std::source_location)201907L<source_location>(C++20)P1208R6
__cpp_lib_spanstd::span202002L<span>(C++20)P0122R7 LWG3274 P1024R3 P1976R2
__cpp_lib_spanstreamstd::spanbuf, std::spanstream202106L<span_stream>(C++23)P0448R4
__cpp_lib_ssizestd::ssize 和无符号 std::span::size201902L<iterator>(C++20)P1227R2
__cpp_lib_stacktrace堆栈跟踪库202011L<stacktrace>(C++23)P0881R7
__cpp_lib_start_lifetime_as显式生命周期管理 (std::start_lifetime_as)202207L<memory>(C++23)P2590R2
__cpp_lib_starts_ends_with字符串前缀和后缀检查 (std::string 和 std::string_view 的 [starts_with()] 和 [ends_with()])201711L<string> <string_view>(C++20)P0457R2
__cpp_lib_stdatomic_hC 原子操作的兼容头文件202011L<stdatomic.h>(C++23)P0943R6
__cpp_lib_string_containsstd::basic_string 和 std::basic_string_view 的 contains 函数202011L<string> <string_view>(C++23)P1679R3
__cpp_lib_string_resize_and_overwritestd::basic_string::resize_and_overwrite202110L<string>(C++23)P1072R10
__cpp_lib_string_udls字符串类型的用户定义字面量201304L<string>(C++14)N3642
__cpp_lib_string_viewstd::string_view201606L<string> <string_view>(C++17)P0220R1 P0254R2
__cpp_lib_string_viewConstexprIterator201803L<string> <string_view>(C++20)P0858R0 LWG3257
__cpp_lib_syncbuf同步缓冲输出流 (std::syncbuf, std::osyncstream) 和操纵符201803L<syncstream>(C++20)P0053R7 P0753R2
__cpp_lib_three_way_comparison三向比较 (库支持); 将三向比较添加到库中201907L<compare>(C++20)P0768R1 P1614R2
__cpp_lib_to_address将指针转换为原始指针的实用程序 (std::to_address)201711L<memory>(C++20)P0653R2
__cpp_lib_to_arraystd::to_array201907L<array>(C++20)P0325R4
__cpp_lib_to_chars基本字符串转换 (std::to_chars, std::from_chars)201611L<charconv>(C++17)P0067R5 P0682R1 LWG3137
__cpp_lib_to_underlyingstd::to_underlying202102L<utility>(C++23)P1682R2
__cpp_lib_transformation_trait_aliasesTransformationTraits 的别名模板201304L<type_traits>(C++14)N3655
__cpp_lib_transparent_operators透明运算符函数对象 (std::less<> 等)201210L<functional>(C++14)N3421
__cpp_lib_transparent_operators透明 std::owner_less (std::owner_less<void>)201510L<memory> <functional>(C++17)P0074R0
__cpp_lib_tuple_element_tstd::tuple_element_t201402L<tuple>(C++14)N3887
__cpp_lib_tuple_likestd::tuple 和类 tuple 对象 (std::pair, std::array, std::subrange) 之间的兼容性202207L<map> <tuple> <unordered_map> <utility>(C++23)P2165R4
__cpp_lib_tuples_by_type通过类型寻址元组201304L<tuple> <utility>(C++14)N3670
__cpp_lib_type_identitystd::type_identity201806L<type_traits>(C++20)P0887R1
__cpp_lib_type_trait_variable_templates类型特征变量模板 (std::is_void_v, 等)201510L<type_traits>(C++17)P0006R0
__cpp_lib_uncaught_exceptionsstd::uncaught_exceptions201411L<exception>(C++17)N4259
__cpp_lib_unordered_map_try_emplacestd::unordered_map::try_emplace, std::unordered_map::insert_or_assign201411L<unordered_map>(C++17)N4279
__cpp_lib_unreachablestd::unreachable202202L<utility>(C++23)P0627R6
__cpp_lib_unwrap_refstd::unwrap_ref_decay 和 std::unwrap_reference201811L<type_traits>(C++20)P0318R1 LWG3348
__cpp_lib_variantstd::variant: C++17 的类型安全联合体201606L<variant>(C++17)P0088R3 P0393R3 P0032R3
__cpp_lib_variant派生自 std::variant 的类的 std::visit202102L<variant>(C++17) (DR)P2162R2
__cpp_lib_variant完全 constexpr std::variant202106L<variant>(C++20) (DR)P2231R1
__cpp_lib_void_tstd::void_t201411L<type_traits>(C++17)N3911

示例

正常用法

#ifdef __has_include                           // Check if __has_include is present
# if __has_include(<optional>) // Check for a standard library
# include <optional>
# elif __has_include(<experimental/optional>) // Check for an experimental version
# include <experimental/optional>
# elif __has_include(<boost/optional.hpp>) // Try withan external library
# include <boost/optional.hpp>
# else // Not found at all
# error "Missing <optional>"
# endif
#endif

#ifdef __has_cpp_attribute // Check if __has_cpp_attribute is present
# if __has_cpp_attribute(deprecated) // Check for an attribute
# define DEPRECATED(msg) [[deprecated(msg)]]
# endif
#endif
#ifndef DEPRECATED
# define DEPRECATED(msg)
#endif

DEPRECATED("foo() has been deprecated") void foo();

#if __cpp_constexpr >= 201304 // Check for a specific version of a feature
# define CONSTEXPR constexpr
#else
# define CONSTEXPR inline
#endif

CONSTEXPR int bar(unsigned i)
{
#if __cpp_binary_literals // Check for the presence of a feature
unsigned mask1 = 0b11000000;
unsigned mask2 = 0b00000111;
#else
unsigned mask1 = 0xC0;
unsigned mask2 = 0x07;
#endif
if ( i & mask1 )
return 1;
if ( i & mask2 )
return 2;
return 0;
}

int main(){}

编译器功能转储

以下程序转储 C++ 编译器功能和属性。

static constexpr struct change_these_options_to_select_what_will_be_printed
{
constexpr static int longest_macro_name { 44 };
constexpr static bool titles = 1;
constexpr static bool counters = 1;
constexpr static bool attributes = 1;
constexpr static bool standard_values = 1;
constexpr static bool compiler_specific = 1;
constexpr static bool core_features = 1;
constexpr static bool lib_features = 1;
constexpr static bool supported_features = 1;
constexpr static bool unsupported_features = 1;
constexpr static bool sort_by_date = 0;
constexpr static bool separate_year_month = 1;
constexpr static bool separated_revisions = 1;
constexpr static bool latest_revisions = 1;
constexpr static bool cxx98 = 0;
constexpr static bool cxx11 = 1;
constexpr static bool cxx14 = 1;
constexpr static bool cxx17 = 1;
constexpr static bool cxx20 = 1;
constexpr static bool cxx23 = 1;
constexpr static bool cxx26 = 0;
} print;

#if __cplusplus < 201100
# error "C++11 or better is required"
#endif

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <utility>
#include <vector>

#ifdef __has_include
# if __has_include(<version>)
# include <version>
# endif
#endif

// Expect a string that starts with6-decimal-digits or with'_' (if unsupported)
#define COMPILER_VALUE_INT(n) #n [0] == '_' ? 0 : \
(#n[5] - '0') + (#n[4] - '0') * 10 + (#n[3] - '0') * 100 + \
(#n[2] - '0') * 1000 + (#n[1] - '0') * 10000 + (#n[0] - '0') * 100000
#define COMPILER_FEATURE_ENTRY(expect, name) { #name, COMPILER_VALUE_INT(name), expect },

#ifdef __has_cpp_attribute
# define COMPILER_ATTRIBUTE(expect, name) { #name, __has_cpp_attribute(name), expect },
#else
# define COMPILER_ATTRIBUTE(expect, name) { #name, COMPILER_VALUE_INT(name), expect },
#endif

#define COMPILER_SPECIFIC_STRING(value) #value
#define COMPILER_SPECIFIC_ENTRY(name) { #name, COMPILER_SPECIFIC_STRING(name) },

class CompilerFeature
{
char const* name_; long data_; long std_;
public:
constexpr CompilerFeature(char const* name, long data, long std)
: name_(name), data_(data), std_(std) {}
constexpr CompilerFeature(CompilerFeature const&) = default;
CompilerFeature& operator=(CompilerFeature const&) = default;
bool operator<(CompilerFeature const& rhs) const
{ return std::strcmp(name_, rhs.name_) < 0; }
bool operator==(CompilerFeature const& rhs) const
{ return std::strcmp(name_, rhs.name_) == 0; }
constexpr bool supported() const { return data_ >= std_; }
constexpr bool maybe() const { return data_ > 0; }
constexpr char const* name() const { return name_; }
constexpr long std() const { return std_; }
constexpr long data() const { return data_; }
void data(long x) { data_ = x; }
};

static /*constexpr*/ std::pair<const char*, const char*> compiler[] = {
COMPILER_SPECIFIC_ENTRY(__cplusplus) //< not compiler specific, but useful :)
COMPILER_SPECIFIC_ENTRY(__clang_major__)
COMPILER_SPECIFIC_ENTRY(__clang_minor__)
COMPILER_SPECIFIC_ENTRY(__clang_patchlevel__)
COMPILER_SPECIFIC_ENTRY(__GNUG__)
COMPILER_SPECIFIC_ENTRY(__GNUC_MINOR__)
COMPILER_SPECIFIC_ENTRY(__GNUC_PATCHLEVEL__)
// Add your favorite compiler specific macros. Undefined ones will not be printed.
};

static constexpr CompilerFeature cxx98_core[] = {
COMPILER_FEATURE_ENTRY(199711L, __cpp_exceptions)
COMPILER_FEATURE_ENTRY(199711L, __cpp_rtti)
};

static constexpr CompilerFeature cxx11_core[] = {
COMPILER_FEATURE_ENTRY(200704L, __cpp_alias_tiplates)
COMPILER_FEATURE_ENTRY(200809L, __cpp_attributes)
COMPILER_FEATURE_ENTRY(200704L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201711L, __cpp_constexpr_in_decltype)
COMPILER_FEATURE_ENTRY(200707L, __cpp_decltype)
COMPILER_FEATURE_ENTRY(200604L, __cpp_delegating_constructors)
COMPILER_FEATURE_ENTRY(201511L, __cpp_inheriting_constructors)
COMPILER_FEATURE_ENTRY(200806L, __cpp_initializer_lists)
COMPILER_FEATURE_ENTRY(200907L, __cpp_lambdas)
COMPILER_FEATURE_ENTRY(200809L, __cpp_nsdmi)
COMPILER_FEATURE_ENTRY(200907L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(200710L, __cpp_raw_strings)
COMPILER_FEATURE_ENTRY(200710L, __cpp_ref_qualifiers)
COMPILER_FEATURE_ENTRY(200610L, __cpp_rvalue_references)
COMPILER_FEATURE_ENTRY(200410L, __cpp_static_assert)
COMPILER_FEATURE_ENTRY(200806L, __cpp_threadsafe_static_init)
COMPILER_FEATURE_ENTRY(200704L, __cpp_unicode_characters)
COMPILER_FEATURE_ENTRY(200710L, __cpp_unicode_literals)
COMPILER_FEATURE_ENTRY(200809L, __cpp_user_defined_literals)
COMPILER_FEATURE_ENTRY(200704L, __cpp_variadic_tiplates)
};

static constexpr CompilerFeature cxx14_core[] = {
COMPILER_FEATURE_ENTRY(201304L, __cpp_aggregate_nsdmi)
COMPILER_FEATURE_ENTRY(201304L, __cpp_binary_literals)
COMPILER_FEATURE_ENTRY(201304L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201304L, __cpp_decltype_auto)
COMPILER_FEATURE_ENTRY(201304L, __cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(201304L, __cpp_init_captures)
COMPILER_FEATURE_ENTRY(201304L, __cpp_return_type_deduction)
COMPILER_FEATURE_ENTRY(201309L, __cpp_sized_deallocation)
COMPILER_FEATURE_ENTRY(201304L, __cpp_variable_tiplates)
};
static constexpr CompilerFeature cxx14_lib[] = {
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_chrono_udls)
COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_complex_udls)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_exchange_function)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_generic_associative_lookup)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integer_sequence)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integral_constant_callable)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_is_final)
COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_is_null_pointer)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_make_reverse_iterator)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_make_unique)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_null_iterators)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_quoted_string_io)
COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_result_of_sfinae)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_robust_nonmodifying_seq_ops)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_shared_timed_mutex)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_string_udls)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_transformation_trait_aliases)
COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_tuple_elient_t)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_tuples_by_type)
};

static constexpr CompilerFeature cxx17_core[] = {
COMPILER_FEATURE_ENTRY(201603L, __cpp_aggregate_bases)
COMPILER_FEATURE_ENTRY(201606L, __cpp_aligned_new)
COMPILER_FEATURE_ENTRY(201603L, __cpp_capture_star_this)
COMPILER_FEATURE_ENTRY(201603L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201703L, __cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(201411L, __cpp_enumerator_attributes)
COMPILER_FEATURE_ENTRY(201603L, __cpp_fold_expressions)
COMPILER_FEATURE_ENTRY(201606L, __cpp_guaranteed_copy_elision)
COMPILER_FEATURE_ENTRY(201603L, __cpp_hex_float)
COMPILER_FEATURE_ENTRY(201606L, __cpp_if_constexpr)
COMPILER_FEATURE_ENTRY(201606L, __cpp_inline_variables)
COMPILER_FEATURE_ENTRY(201411L, __cpp_namespace_attributes)
COMPILER_FEATURE_ENTRY(201510L, __cpp_noexcept_function_type)
COMPILER_FEATURE_ENTRY(201411L, __cpp_nontype_tiplate_args)
COMPILER_FEATURE_ENTRY(201606L, __cpp_nontype_tiplate_parameter_auto)
COMPILER_FEATURE_ENTRY(201603L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(201411L, __cpp_static_assert)
COMPILER_FEATURE_ENTRY(201606L, __cpp_structured_bindings)
COMPILER_FEATURE_ENTRY(201611L, __cpp_tiplate_tiplate_args)
COMPILER_FEATURE_ENTRY(201611L, __cpp_variadic_using)
};
static constexpr CompilerFeature cxx17_lib[] = {
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_addressof_constexpr)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_allocator_traits_is_always_equal)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_any)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_apply)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_as_const)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_atomic_is_always_lock_free)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_bool_constant)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_boyer_moore_searcher)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_byte)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_clamp)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_enable_shared_from_this)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_execution)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_filesysti)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_gcd_lcm)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_hardware_interference_size)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_has_unique_object_representations)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_hypot)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_incomplete_container_elients)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_invoke)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_aggregate)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_invocable)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_is_swappable)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_launder)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_logical_traits)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_make_from_tuple)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_map_try_iplace)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_math_special_functions)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_miory_resource)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_node_extract)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_nonmiber_container_access)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_not_fn)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_parallel_algorithm)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_raw_miory_algorithms)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_sample)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_scoped_lock)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_shared_mutex)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_shared_ptr_weak_type)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_to_chars)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_type_trait_variable_tiplates)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_uncaught_exceptions)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_unordered_map_try_iplace)
COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_variant)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_void_t)
};

static constexpr CompilerFeature cxx20_core[] = {
COMPILER_FEATURE_ENTRY(201902L, __cpp_aggregate_paren_init)
COMPILER_FEATURE_ENTRY(202207L, __cpp_char8_t)
COMPILER_FEATURE_ENTRY(202002L, __cpp_concepts)
COMPILER_FEATURE_ENTRY(201806L, __cpp_conditional_explicit)
COMPILER_FEATURE_ENTRY(202211L, __cpp_consteval)
COMPILER_FEATURE_ENTRY(202002L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201907L, __cpp_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(201907L, __cpp_constinit)
COMPILER_FEATURE_ENTRY(201907L, __cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(201707L, __cpp_designated_initializers)
COMPILER_FEATURE_ENTRY(201707L, __cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(201902L, __cpp_impl_coroutine)
COMPILER_FEATURE_ENTRY(201806L, __cpp_impl_destroying_delete)
COMPILER_FEATURE_ENTRY(201907L, __cpp_impl_three_way_comparison)
COMPILER_FEATURE_ENTRY(201803L, __cpp_init_captures)
COMPILER_FEATURE_ENTRY(201907L, __cpp_modules)
COMPILER_FEATURE_ENTRY(201911L, __cpp_nontype_tiplate_args)
COMPILER_FEATURE_ENTRY(201907L, __cpp_using_enum)
};
static constexpr CompilerFeature cxx20_lib[] = {
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_assume_aligned)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_flag_test)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_float)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_lock_free_type_aliases)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_atomic_ref)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_shared_ptr)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_atomic_value_initialization)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_wait)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_barrier)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bind_front)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_bit_cast)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bitops)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_bounded_array_traits)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_char8_t)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_concepts)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_constexpr_algorithms)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_constexpr_complex)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_functional)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_iterator)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_miory)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_constexpr_numeric)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_string)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_string_view)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_tuple)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_utility)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_vector)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_coroutine)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_destroying_delete)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_endian)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_erase_if)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_execution)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_format)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_generic_unordered_lookup)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_int_pow2)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_integer_comparison_functions)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_interpolate)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_is_constant_evaluated)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_layout_compatible)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_is_nothrow_convertible)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_pointer_interconvertible)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_jthread)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_latch)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_list_riove_return_type)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_math_constants)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_polymorphic_allocator)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_riove_cvref)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_siaphore)
COMPILER_FEATURE_ENTRY(201707L, __cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_shift)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_smart_ptr_for_overwrite)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_source_location)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_span)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_ssize)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_starts_ends_with)
COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_syncbuf)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_three_way_comparison)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_to_address)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_to_array)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_type_identity)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_unwrap_ref)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_variant)
};

static constexpr CompilerFeature cxx23_core[] = {
COMPILER_FEATURE_ENTRY(202110L, __cpp_auto_cast)
COMPILER_FEATURE_ENTRY(202211L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(202110L, __cpp_explicit_this_parameter)
COMPILER_FEATURE_ENTRY(202106L, __cpp_if_consteval)
COMPILER_FEATURE_ENTRY(202207L, __cpp_implicit_move)
COMPILER_FEATURE_ENTRY(202211L, __cpp_multidimensional_subscript)
COMPILER_FEATURE_ENTRY(202207L, __cpp_named_character_escapes)
COMPILER_FEATURE_ENTRY(202211L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(202011L, __cpp_size_t_suffix)
COMPILER_FEATURE_ENTRY(202207L, __cpp_static_call_operator)
};
static constexpr CompilerFeature cxx23_lib[] = {
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_adaptor_iterator_pair_constructor)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_algorithm_iterator_requirients)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_allocate_at_least)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_associative_heterogeneous_erasure)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_barrier)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_bind_back)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_byteswap)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference_wrapper)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_concepts)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_bitset)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_charconv)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_cmath)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_miory)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_constexpr_typeinfo)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_containers_ranges)
COMPILER_FEATURE_ENTRY(202211L, __cpp_lib_expected)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_map)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_set)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format_ranges)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_formatters)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_forward_like)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_generator)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_invoke_r)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ios_noreplace)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_is_implicit_lifetime)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_is_scoped_enum)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_mdspan)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_modules)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_move_iterator_concept)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_move_only_function)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_out_ptr)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_print)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_const)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_rvalue)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_cartesian_product)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk_by)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_contains)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges_enumerate)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_find_last)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_fold)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_iota)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_join_with)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_repeat)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_slide)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_ranges_starts_ends_with)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_stride)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_to_container)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges_zip)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_reference_from_tiporary)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_shift)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_spanstream)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stacktrace)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_start_lifetime_as)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stdatomic_h)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_string_contains)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_string_resize_and_overwrite)
COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_to_underlying)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_tuple_like)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_unreachable)
};

static constexpr CompilerFeature cxx26_core[] = {
//< Continue to Populate
COMPILER_FEATURE_ENTRY(202304L, __cpp_core_TODO)
};
static constexpr CompilerFeature cxx26_lib[] = {
//< Continue to Populate
COMPILER_FEATURE_ENTRY(202304L, __cpp_lib_TODO)
};

static constexpr CompilerFeature attributes[] = {
COMPILER_ATTRIBUTE(202207L, assume)
COMPILER_ATTRIBUTE(200809L, carries_dependency)
COMPILER_ATTRIBUTE(201309L, deprecated)
COMPILER_ATTRIBUTE(201603L, fallthrough)
COMPILER_ATTRIBUTE(201803L, likely)
COMPILER_ATTRIBUTE(201603L, maybe_unused)
COMPILER_ATTRIBUTE(201803L, no_unique_address)
COMPILER_ATTRIBUTE(201907L, nodiscard)
COMPILER_ATTRIBUTE(200809L, noreturn)
COMPILER_ATTRIBUTE(201803L, unlikely)
};

inline void show_compiler_specific_info()
{
std::printf("Compiler specific macros:\n");
for (auto co : compiler)
if (std::strcmp(co.first, co.second))
std::printf("%*s %s\n", -print.longest_macro_name, co.first, co.second);
}

inline void print_compiler_feature(const CompilerFeature& x)
{
if (not ((print.supported_features and x.maybe()) or
(print.unsupported_features and not x.maybe())))
return;
auto print_year_month= [](long n)
{
return std::printf("%ld%s%02ld",
n / 100, print.separate_year_month? "-" : "", n % 100);
};
std::printf("%*s ", -print.longest_macro_name, x.name());
x.maybe() ? print_year_month(x.data()) :
std::printf("------%s", print.separate_year_month? "-" : "");
if (print.standard_values)
std::printf(" %c ", (x.supported() ? (x.data() > x.std() ? '>' : '=') : '<')),
print_year_month(x.std());
std::puts("");
}

tiplate<class Container>
inline void show(char const* const title, Container const& co)
{
if (print.titles)
{
std::printf("%-s (", title);
if (print.counters)
{
std::printf("%ld/", std::count_if(std::begin(co), std::end(co),
[](CompilerFeature x)
{
return x.supported();
}));
}
std::printf("%td)\n", std::distance(std::begin(co), std::end(co)));
}
if (print.sort_by_date)
{
std::vector<CompilerFeature> v(std::begin(co), std::end(co));
std::stable_sort(v.begin(), v.end(),
[](CompilerFeature const& lhs, CompilerFeature const& rhs)
{
return lhs.data() < rhs.data();
});
std::for_each(v.cbegin(), v.cend(), print_compiler_feature);
}
else
std::for_each(std::begin(co), std::end(co), print_compiler_feature);
std::puts("");
}

inline void show_latest()
{
auto latest_rev = []() -> int
{
return print.cxx26 ? 26 : print.cxx23 ? 23 : print.cxx20 ? 20 :
print.cxx17 ? 17 : print.cxx14 ? 14 : print.cxx11 ? 11 : 98;
};
std::vector<CompilerFeature> latest;
auto add = [&latest](CompilerFeature x)
{
auto i = std::lower_bound(latest.begin(), latest.end(), x);
if (i == latest.end() or not (*i == x))
latest.insert(i, x);
else if (i->data() < x.data())
i->data(x.data());
};
char text[64];
latest.reserve(512); // max macros
if (print.core_features)
{ // preserve reverse revision insersion order!
if (print.cxx26) std::for_each(std::begin(cxx26_core), std::end(cxx26_core), add);
if (print.cxx23) std::for_each(std::begin(cxx23_core), std::end(cxx23_core), add);
if (print.cxx20) std::for_each(std::begin(cxx20_core), std::end(cxx20_core), add);
if (print.cxx17) std::for_each(std::begin(cxx17_core), std::end(cxx17_core), add);
if (print.cxx14) std::for_each(std::begin(cxx14_core), std::end(cxx14_core), add);
if (print.cxx11) std::for_each(std::begin(cxx11_core), std::end(cxx11_core), add);
if (print.cxx98) std::for_each(std::begin(cxx98_core), std::end(cxx98_core), add);
std::snprintf(text, sizeof text, "ALL CORE MACROS UP TO C++%02i", latest_rev());
show(text, latest);
}
latest.clear();
if (print.lib_features)
{ // preserve reverse revision insersion order!
if (print.cxx26) std::for_each(std::begin(cxx26_lib), std::end(cxx26_lib), add);
if (print.cxx23) std::for_each(std::begin(cxx23_lib), std::end(cxx23_lib), add);
if (print.cxx20) std::for_each(std::begin(cxx20_lib), std::end(cxx20_lib), add);
if (print.cxx17) std::for_each(std::begin(cxx17_lib), std::end(cxx17_lib), add);
if (print.cxx14) std::for_each(std::begin(cxx14_lib), std::end(cxx14_lib), add);
std::snprintf(text, sizeof text, "ALL LIB MACROS UP TO C++%02i", latest_rev());
show(text, latest);
}
}

int main()
{
if (print.separated_revisions)
{
if (print.cxx98 and print.core_features) show("C++98 CORE", cxx98_core);
if (print.cxx11 and print.core_features) show("C++11 CORE", cxx11_core);
if (print.cxx14 and print.core_features) show("C++14 CORE", cxx14_core);
if (print.cxx14 and print.lib_features ) show("C++14 LIB" , cxx14_lib);
if (print.cxx17 and print.core_features) show("C++17 CORE", cxx17_core);
if (print.cxx17 and print.lib_features ) show("C++17 LIB" , cxx17_lib);
if (print.cxx20 and print.core_features) show("C++20 CORE", cxx20_core);
if (print.cxx20 and print.lib_features ) show("C++20 LIB" , cxx20_lib);
if (print.cxx23 and print.core_features) show("C++23 CORE", cxx23_core);
if (print.cxx23 and print.lib_features ) show("C++23 LIB" , cxx23_lib);
if (print.cxx26 and print.core_features) show("C++26 CORE", cxx26_core);
if (print.cxx26 and print.lib_features ) show("C++26 LIB" , cxx26_lib);
}
if (print.latest_revisions) show_latest();
if (print.attributes) show("ATTRIBUTES", attributes);
if (print.compiler_specific) show_compiler_specific_info();
}
可能结果
C++11 CORE (20/20)
__cpp_alias_tiplates 2007-04 = 2007-04
__cpp_attributes 2008-09 = 2008-09
__cpp_constexpr 2021-10 > 2007-04
__cpp_constexpr_in_decltype 2017-11 = 2017-11
... truncated ...

C++14 CORE (9/9)
__cpp_aggregate_nsdmi 2013-04 = 2013-04
__cpp_binary_literals 2013-04 = 2013-04
__cpp_constexpr 2021-10 > 2013-04
... truncated ...

C++14 LIB (20/20)
__cpp_lib_chrono_udls 2013-04 = 2013-04
__cpp_lib_complex_udls 2013-09 = 2013-09
__cpp_lib_exchange_function 2013-04 = 2013-04
... truncated ...

C++17 CORE (20/20)
__cpp_aggregate_bases 2016-03 = 2016-03
__cpp_aligned_new 2016-06 = 2016-06
__cpp_capture_star_this 2016-03 = 2016-03
__cpp_constexpr 2021-10 > 2016-03
... truncated ...

C++17 LIB (49/49)
__cpp_lib_addressof_constexpr 2016-03 = 2016-03
__cpp_lib_allocator_traits_is_always_equal 2014-11 = 2014-11
... truncated ...

C++20 CORE (17/18)
__cpp_aggregate_paren_init 2019-02 = 2019-02
__cpp_char8_t 2018-11 = 2018-11
__cpp_concepts 2020-02 = 2020-02
... truncated ...

C++20 LIB (64/67)
__cpp_lib_array_constexpr 2018-11 = 2018-11
__cpp_lib_assume_aligned 2018-11 = 2018-11
__cpp_lib_atomic_flag_test 2019-07 = 2019-07
... truncated ...

C++23 CORE (2/11)
__cpp_char8_t 2018-11 < 2022-07
__cpp_consteval 2018-11 < 2022-11
... truncated ...

C++23 LIB (16/64)
__cpp_lib_adaptor_iterator_pair_constructor 2021-06 = 2021-06
__cpp_lib_algorithm_iterator_requirients ------- < 2022-07
__cpp_lib_allocate_at_least ------- < 2023-02
__cpp_lib_associative_heterogeneous_erasure ------- < 2021-10
__cpp_lib_barrier 2019-07 < 2023-02
... truncated ...

ALL CORE MACROS UP TO C++23 (55/65)
__cpp_aggregate_bases 2016-03 = 2016-03
__cpp_aggregate_nsdmi 2013-04 = 2013-04
__cpp_aggregate_paren_init 2019-02 = 2019-02
__cpp_alias_tiplates 2007-04 = 2007-04
... truncated ...

ALL LIB MACROS UP TO C++23 (135/185)
__cpp_lib_adaptor_iterator_pair_constructor 2021-06 = 2021-06
__cpp_lib_addressof_constexpr 2016-03 = 2016-03
__cpp_lib_algorithm_iterator_requirients ------- < 2022-07
__cpp_lib_allocate_at_least ------- < 2023-02
__cpp_lib_allocator_traits_is_always_equal 2014-11 = 2014-11
... truncated ...

ATTRIBUTES (8/10)
assume ------- < 2022-07
carries_dependency ------- < 2008-09
deprecated 2013-09 = 2013-09
fallthrough 2016-03 = 2016-03
... truncated ...

Compiler specific macros:
__cplusplus 202100L
__GNUG__ 12
__GNUC_MINOR__ 2
__GNUC_PATCHLEVEL__ 1
  1. 关于功能测试建议的官方文档
  2. 用于转储编译器功能的源代码

功能测试 (自 C++20 起)

标准定义了一组 预处理器宏,对应于 C++ 语言和库在 C++更高版本中引入的功能。它们旨在作为一种简单且可移植的方式来检测这些功能的可用性。

属性

pub__has_cpp_attribute( attribute-token )

检查对由 attribute-token (宏展开后)命名的 属性的支持。

对于标准属性,它会扩展到属性添加到工作草案的年和月 (见下表),而供应商特定属性的存在则由非零值确定。

__has_cpp_attribute 可以在 #if#elif 的表达式中展开。它被 #ifdef#ifndef、 #elifdef#elifndef (C++23 起)defined 作为已定义宏处理,但不能用于其他任何地方。

attribute-token属性标准论文(s)
assume[[assume]]202207L(C++23)P1774R8
carries_dependency[[carries_dependency]]200809L(C++11)N2556, N2643
deprecated[[deprecated]]201309L(C++14)N3760
fallthrough[[fallthrough]]201603L(C++17)P0188R1
likely[[likely]]201803L(C++20)P0479R5
maybe_unused[[maybe_unused]]201603L(C++17)P0212R1
no_unique_address[[no_unique_address]]201803L(C++20)P0840R2
nodiscard[[nodiscard]]201603L
201907L
(C++17)
(C++20)
P0189R1
P1301R4
noreturn[[noreturn]]200809L(C++11)N2761
unlikely[[unlikely]]201803L(C++20)P0479R5

语言特性

以下宏在每个翻译单元中都预定义了。每个宏都扩展为一个整数文字,表示相应的特性在工作草案中包含的年和月。

当特性发生重大变化时,宏会相应更新。

宏名称特性标准论文(s)
__cpp_aggregate_bases带有基类的 聚合类201603L(C++17)P0017R1
__cpp_aggregate_nsdmi带有 成员默认初始化器聚合类201304L(C++14)N3653
__cpp_aggregate_paren_init直接初始化 形式的 聚合初始化201902L(C++20)P0960R3
__cpp_alias_templates别名模板200704L(C++11)N2258
__cpp_aligned_new面向过对齐数据的动态内存分配201606L(C++17)P0035R4
__cpp_attributes属性200809L(C++11)N2761
__cpp_auto_castauto(x)auto{x}202110L(C++23)P0849R8
__cpp_binary_literals二进制字面量201304L(C++14)N3472
__cpp_capture_star_thisLambda 捕获 *this 按值方式表示为 [=,*this]201603L(C++17)P0018R3
__cpp_char8_tchar8_t201811L(C++20)P0482R6
__cpp_char8_tchar8_t 兼容性和可移植性修复 ( 允许从 UTF-8 字符串字面量 初始化 (无符号) char 数组)202207L(C++20)(DR)P2513R4
__cpp_concepts概念201907L(C++20)P0734R0
P1084R2
P1452R2
__cpp_concepts条件化的平凡特殊成员函数202002L(C++20)P0848R3
P2493R0
__cpp_conditional_explicitexplicit(bool)201806L(C++20)P0892R2
__cpp_consteval立即函数201811L(C++20)P1073R3
__cpp_consteval使 consteval 能够向上传播202211L(C++20)(DR)P2564R3
__cpp_constexprconstexpr200704L(C++11)N2235
__cpp_constexpr宽松的 constexpr非 const 的 constexpr 成员函数201304L(C++14)N3652
__cpp_constexprConstexpr lambda201603L(C++17)P0170R1
__cpp_constexpr常量表达式中的 虚函数 调用201806L(C++20)P1064R0
__cpp_constexpr常量表达式中的 try-catch 块、dynamic_cast 和多态 typeid201811L(C++20)P1002R1
P1327R1
__cpp_constexpr常量表达式函数中的平凡 默认初始化asm 声明201907L(C++20)P1331R2
P1668R1
__cpp_constexpr常量求值中更改联合体的活动成员202002L(C++20)P1330R0
__cpp_constexpr常量表达式函数中的非字面量变量、标签和 goto 语句202110L(C++23)P2242R3
__cpp_constexpr放宽对 constexpr 函数和函数模板的某些限制202207L(C++23)P2448R2
__cpp_constexpr允许在 constexpr 函数中使用静态 constexpr 变量202211L(C++23)P2647R1
__cpp_constexpr_dynamic_alloc常量表达式函数中的动态存储期操作201907L(C++20)P0784R7
__cpp_constexpr_in_decltype在需要常量求值时生成函数和变量定义201711L(C++11)(DR)P0859R0
__cpp_constinitconstinit201907L(C++20)P1143R2
__cpp_decltypedecltype200707L(C++11)N2343
__cpp_decltype_auto普通函数的返回类型推导201304L(C++14)N3638
__cpp_deduction_guides类模板的模板参数推导201703L(C++17)P0091R3
P0512R0
P0620R0
__cpp_deduction_guides聚合体和别名的 CTAD201907L(C++20)P1814R0
P1816R0
__cpp_delegating_constructors委托构造函数200604L(C++11)N1986
__cpp_designated_initializers指定初始化器201707L(C++20)P0329R4
__cpp_enumerator_attributes枚举数的属性201411L(C++17)N4266
__cpp_explicit_this_parameter显式对象参数202110L(C++23)P0847R7
__cpp_fold_expressions折叠表达式201603L(C++17)N4295
P0036R0
__cpp_generic_lambdas泛型 lambda 表达式201304L(C++14)N3649
__cpp_generic_lambdas泛型 lambda 的显式模板参数列表201707L(C++20)P0428R2
__cpp_guaranteed_copy_elision通过简化的 值类别 实现保证的复制省略201606L(C++17)P0135R1
__cpp_hex_float十六进制浮点文字量201603L(C++17)P0245R1
__cpp_if_constevalconsteval if202106L(C++23)P1938R3
__cpp_if_constexprconstexpr if201606L(C++17)P0292R2
__cpp_impl_coroutine协程 (编译器支持)201902L(C++20)P0912R5
LWG3393
__cpp_impl_destroying_delete销毁 new 运算符 (编译器支持)201806L(C++20)P0722R3
__cpp_impl_three_way_comparison三向比较 (编译器支持)201907L(C++20)P0515R3
P0768R1
P1185R2
P1630R1
__cpp_implicit_move更简单的 隐式移动202207L(C++23)P2266R3
__cpp_inheriting_constructors继承构造函数200802L(C++11)N2540
__cpp_inheriting_constructors继承构造函数的措辞修改201511L(C++11)(DR)P0136R1
__cpp_init_capturesLambda 初始化捕获201304L(C++14)N3648
__cpp_init_captures允许在 Lambda 初始化捕获中使用包展开201803L(C++20)P0780R2
__cpp_initializer_lists列表初始化std::initializer_list200806L(C++11)N2672
__cpp_inline_variables内联变量201606L(C++17)P0386R2
__cpp_lambdasLambda 表达式200907L(C++11)N2927
__cpp_modules模块201907L(C++20)P1103R3
P1811R0
__cpp_multidimensional_subscript多维 下标运算符202110L(C++23)P2128R6
__cpp_multidimensional_subscriptstatic operator[]202211L(C++23)P2589R1
__cpp_named_character_escapes命名 通用字符转义202207L(C++23)P2071R2
__cpp_namespace_attributes命名空间的属性201411L(C++17)N4266
__cpp_noexcept_function_type异常规范 纳入类型系统201510L(C++17)P0012R1
__cpp_nontype_template_args允许对所有 非类型模板参数 进行常量求值201411L(C++17)N4268
__cpp_nontype_template_args类类型和浮点类型作为 非类型模板参数201911L(C++20)P1907R1
__cpp_nontype_template_parameter_auto使用 auto 声明 非类型模板参数201606L(C++17)P0127R2
__cpp_nsdmi非静态数据成员初始化器200809L(C++11)N2756
__cpp_range_based_for基于范围的 for 循环200907L(C++11)N2930
__cpp_range_based_for带有不同 begin/end 类型的 基于范围的 for 循环201603L(C++17)P0184R0
__cpp_range_based_for基于范围的 for 循环中的生命周期扩展202211L(C++23)P2718R0
__cpp_raw_strings原始字符串字面量200710L(C++11)N2442
__cpp_ref_qualifiers引用限定符200710L(C++11)N2439
__cpp_return_type_deduction普通函数的返回类型推导201304L(C++14)N3638
__cpp_rvalue_references右值引用200610L(C++11)N2118
__cpp_size_t_suffixsize_t 及其有符号版本的字面量后缀202011L(C++23)P0330R8
__cpp_sized_deallocation带尺寸的 deallocation201309L(C++14)N3778
__cpp_static_assertstatic_assert200410L(C++11)N1720
__cpp_static_assert单参数 static_assert201411L(C++17)N3928
__cpp_static_call_operatorstatic operator()202207L(C++23)P1169R4
__cpp_structured_bindings结构化绑定201606L(C++17)P0217R3
__cpp_template_template_args匹配 模板模板参数201611L(C++17)P0522R0
__cpp_threadsafe_static_init带并发的动态初始化和销毁200806L(C++11)N2660
__cpp_unicode_characters新的字符类型 (char16_tchar32_t)200704L(C++11)N2249
__cpp_unicode_literalsUnicode 字符串字面量200710L(C++11)N2442
__cpp_user_defined_literals用户定义字面量200809L(C++11)N2765
__cpp_using_enumusing enum201907L(C++20)P1099R5
__cpp_variable_templates变量模板201304L(C++14)N3651
__cpp_variadic_templates可变参数模板200704L(C++11)N2242
__cpp_variadic_usingusing 声明 中使用包展开201611L(C++17)P0195R2

库特性

如果包含了 <version> 头文件或下表中任何相应的头文件,则定义以下宏。每个宏都扩展为一个整数文字,表示相应的特性在工作草案中包含的年和月。

当特性发生重大变化时,宏会相应更新。

宏名称特性头文件标准论文(s)
__cpp_lib_adaptor_iterator_pair_constructor用于 std::stack 和 std::queue 的适配器迭代器对构造函数202106L<queue> <stack>(C++23)P1425R4
__cpp_lib_addressof_constexprConstexpr std::addressof201603L<memory>(C++17)LWG2296
__cpp_lib_algorithm_iterator_requirementsRanges 迭代器作为非 Ranges 算法 的输入202207L<algorithm> <memory> <numeric>(C++23)P2408R5
__cpp_lib_allocate_at_least分配器接口中的大小反馈,例如:std::allocator::allocate_at_least, std::allocator_traits::allocate_at_least202302L<memory>(C++23)P0401R6 P2652R2
__cpp_lib_allocator_traits_is_always_equalstd::allocator_traits::is_always_equal201411L<memory> <scoped_allocator> <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set>(C++17)N4258
__cpp_lib_anystd::any201606L<any>(C++17)P0220R1 P0032R3
__cpp_lib_applystd::apply201603L<tuple>(C++17)P0220R1
__cpp_lib_array_constexprstd::reverse_iterator、std::move_iterator、std::array 和 范围访问 的 Constexpr201603L<iterator> <array>(C++17)P0031R0
__cpp_lib_array_constexprConstexprIterator; std::array 的常量表达式比较;杂项常量表达式部分 (std::array::fill 等)201811L<iterator> <array>(C++20)P0858R0 LWG3257 P1023R0 P1032R1
__cpp_lib_as_conststd::as_const201510L<utility>(C++17)P0007R1
__cpp_lib_associative_heterogeneous_erasure关联容器无序关联容器 中进行异构擦除202110L<map> <set> <unordered_map> <unordered_set>(C++23)P2077R3
__cpp_lib_assume_alignedstd::assume_aligned201811L<memory>(C++20)P1007R3
__cpp_lib_atomic_flag_teststd::atomic_flag::test201907L<atomic>(C++20)P1135R6
__cpp_lib_atomic_float浮点原子类型201711L<atomic>(C++20)P0020R6
__cpp_lib_atomic_is_always_lock_freeconstexpr atomic<T>::is_always_lock_free201603L<atomic>(C++17)P0152R1
__cpp_lib_atomic_lock_free_type_aliases原子无锁整数类型 (std::atomic_signed_lock_free, std::atomic_unsigned_lock_free)201907L<atomic>(C++20)P1135R6
__cpp_lib_atomic_refstd::atomic_ref201806L<atomic>(C++20)P0019R8
__cpp_lib_atomic_shared_ptrstd::atomic<std::shared_ptr>201711L<memory>(C++20)P0718R2
__cpp_lib_atomic_value_initialization修复原子初始化 (默认值初始化 std::atomic)201911L<atomic> <memory>(C++20)P0883R2
__cpp_lib_atomic_wait高效的 std::atomic 等待201907L<atomic>(C++20)P1135R6
__cpp_lib_barrierstd::barrier201907L<barrier>(C++20)P1135R6
__cpp_lib_barrierstd::barrier 的阶段完成保证202302L<barrier>(C++23)P2588R3
__cpp_lib_bind_backstd::bind_back202202L<functional>(C++23)P2387R3
__cpp_lib_bind_frontstd::bind_front201907L<functional>(C++20)P0356R5 P1651R0
__cpp_lib_bit_caststd::bit_cast201806L<bit>(C++20)P0476R2
__cpp_lib_bitops位运算201907L<bit>(C++20)P0553R4
__cpp_lib_bool_constantstd::bool_constant201505L<type_traits>(C++17)N4389
__cpp_lib_bounded_array_traitsstd::is_bounded_array, std::is_unbounded_array201902L<type_traits>(C++20)P1357R1
__cpp_lib_boyer_moore_searcher搜索器201603L<functional>(C++17)P0220R1
__cpp_lib_bytestd::byte201603L<cstddef>(C++17)P0298R3
__cpp_lib_byteswapstd::byteswap202110L<bit>(C++23)P1272R4
__cpp_lib_char8_t对 char8_t 的库支持201907L<atomic> <filesysti> <istream> <limits> <locale> <ostream> <string> <string_view>(C++20)P0482R6 P1423R3
__cpp_lib_chronostd::chrono::duration 和 std::chrono::time_point 的舍入函数201510L<chrono>(C++17)P0092R1
__cpp_lib_chronostd::chrono::duration 和 std::chrono::time_point 所有成员函数的 Constexpr201611L<chrono>(C++17)P0505R0
__cpp_lib_chrono日历时区201907L<chrono>(C++20)P0355R7 P1466R3
__cpp_lib_chrono_udls时间类型的用户定义字面量201304L<chrono>(C++14)N3642
__cpp_lib_clampstd::clamp201603L<algorithm>(C++17)P0025R0
__cpp_lib_common_reference使 std::common_reference_t of std::reference_wrapper 成为引用类型202302L<type_traits>(C++23)P2655R3
__cpp_lib_common_reference_wrapper使 std::common_reference_t of std::reference_wrapper 成为引用类型202302L<functional>(C++23)P2655R3
__cpp_lib_complex_udlsstd::complex 的用户定义字面量201309L<complex>(C++14)N3779
__cpp_lib_concepts标准库概念202002L<concepts>(C++20)P0898R3 P1754R1 P1964R2
__cpp_lib_concepts用于 equality_comparable_with、totally_ordered_with 和 three_way_comparable_with 的仅移动类型202207L<compare> <concepts>(C++23)P2404R3
__cpp_lib_constexpr_algorithms算法的 Constexpr201806L<algorithm>(C++20)P0202R3 P0879R0 LWG3256
__cpp_lib_constexpr_bitset更 constexpr 的 std::bitset202207L<bitset>(C++23)P2417R2
__cpp_lib_constexpr_charconv为整数类型添加 to_chars 和 from_chars 函数的 constexpr 修饰符202207L<charconv>(C++23)P2291R3
__cpp_lib_constexpr_cmath<cmath> 和 <cstdlib> 中的数学函数的 Constexpr202202L<cmath> <cstdlib>(C++23)P0533R9
__cpp_lib_constexpr_complexstd::complex 的 Constexpr201711L<complex>(C++20)P0415R1
__cpp_lib_constexpr_dynamic_allocstd::allocator 和相关工具的 Constexpr201907L<memory>(C++20)P0784R7
__cpp_lib_constexpr_functional杂项 constexpr 部分 (std::default_searcher);constexpr INVOKE201907L<functional>(C++20)P1032R1 P1065R2
__cpp_lib_constexpr_iterator杂项 constexpr 部分 (std::insert_iterator 等)201811L<iterator>(C++20)P1032R1
__cpp_lib_constexpr_memorystd::pointer_traits 中的 Constexpr201811L<memory>(C++20)P1006R1
__cpp_lib_constexpr_memoryConstexpr std::unique_ptr202202L<memory>(C++23)P2273R3
__cpp_lib_constexpr_numeric<numeric> 中 算法 的 Constexpr201911L<numeric>(C++20)P1645R1
__cpp_lib_constexpr_stringstd::string 的 Constexpr201907L<string>(C++20)P0426R1 P1032R1 P0980R1
__cpp_lib_constexpr_string_view杂项 constexpr 部分 (std::string_view::copy)201811L<string_view>(C++20)P0426R1 P1032R1
__cpp_lib_constexpr_tuple杂项 constexpr 部分 (std::tuple::operator= 等)201811L<tuple>(C++20)P1032R1
__cpp_lib_constexpr_typeinfostd::type_info::operator== 的 Constexpr202106L<typeinfo>(C++23)P1328R1
__cpp_lib_constexpr_utility杂项 constexpr 部分 (std::pair::operator= 等)201811L<utility>(C++20)P1032R1
__cpp_lib_constexpr_vectorstd::vector 的 Constexpr201907L<vector>(C++20)P1004R2
__cpp_lib_containers_ranges容器和字符串的 感知 Ranges 的构造和插入202202L<vector> <list> <forward_list > <map> <set> <unordered_map> <unordered_set> <deque> <queue> <stack> <string>(C++23)P1206R7
__cpp_lib_coroutine协程 (库支持)201902L<coroutine>(C++20)P0912R5 LWG3393
__cpp_lib_destroying_delete销毁 new 运算符 (库支持)201806L<new>(C++20)P0722R3
__cpp_lib_enable_shared_from_thisstd::enable_shared_from_this::weak_from_this201603L<memory>(C++17)P0033R1
__cpp_lib_endianstd::endian201907L<bit>(C++20)P0463R1 P1612R1
__cpp_lib_erase_if统一容器擦除202002L<string> <deque> <forward_list > <list> <vector> <map> <set> <unordered_map> <unordered_set>(C++20)P1209R0 P1115R3
__cpp_lib_exchange_functionstd::exchange201304L<utility>(C++14)N3668
__cpp_lib_execution并行策略201603L<execution>(C++17)P0024R2
__cpp_lib_executionstd::execution::unsequenced_policy201902L<execution>(C++20)P1001R2
__cpp_lib_expected类模板 std::expected202202L<expected>(C++23)P0323R12
__cpp_lib_expectedstd::expected 的单子函数202211L<expected>(C++23)P2505R5
__cpp_lib_filesystem文件系统库201703L<filesystem>(C++17)P0218R1 P0219R1 P0392R0 P0317R1
__cpp_lib_flat_mapstd::flat_map 和 std::flat_multimap202207L<flat_map>(C++23)P0429R9
__cpp_lib_flat_setstd::flat_set 和 std::flat_multiset202207L<flat_set>(C++23)P1222R4 LWG3751
__cpp_lib_format文本格式化201907L<format>(C++20)P0645R10 P1361R2 P1652R1
__cpp_lib_format编译时格式字符串检查;减少 std::vformat_to 的参数化202106L<format>(C++20) (DR)P2216R3
__cpp_lib_format修复 chrono 格式化器的区域设置处理;支持非 const 可格式化类型202110L<format>(C++20) (DR)P2372R3 P2418R2
__cpp_lib_format公开 std::basic_format_string;阐明本地化 chrono 类型格式化中的编码处理202207L<format>(C++23)P2419R2 P2508R1
__cpp_lib_format_ranges格式化范围202207L<format>(C++23)P2286R8 P2585R1 LWG3750
__cpp_lib_formatters格式化 std::thread::id 和 std::stacktrace202302L<stacktrace> <thread>(C++23)P2693R1
__cpp_lib_forward_likestd::forward_like202207L<utility>(C++23)P2445R1
__cpp_lib_gcd_lcmstd::gcd, std::lcm201606L<numeric>(C++17)P0295R0
__cpp_lib_generatorstd::generator: 用于范围的同步协程生成器202207L<generator>(C++23)P2502R2
__cpp_lib_generic_associative_lookup关联容器 中进行异构比较查找201304L<map> <set>(C++14)N3657
__cpp_lib_generic_unordered_lookup无序关联容器 中进行异构比较查找201811L<unordered_map> <unordered_set>(C++20)P0919R3
__cpp_lib_hardware_interference_sizeconstexpr std::hardware_interference_size201703L<new>(C++17)P0154R1
__cpp_lib_has_unique_object_representationsstd::has_unique_object_representations201606L<type_traits>(C++17)P0258R2
__cpp_lib_hypot3 参数重载的 std::hypot201603L<cmath>(C++17)P0030R1
__cpp_lib_incomplete_container_elements对 std::forward_list、std::list 和 std::vector 的最小不完整类型支持201505L<forward_list > <list> <vector>(C++17)N4510
__cpp_lib_int_pow2整数幂运算 (std::has_single_bit, std::bit_ceil, std::bit_floor, std::bit_width)202002L<bit>(C++20)P0556R3 P1956R1
__cpp_lib_integer_comparison_functions整数比较函数202002L<utility>(C++20)P0586R2
__cpp_lib_integer_sequence编译时整数序列201304L<utility>(C++14)N3658
__cpp_lib_integral_constant_callablestd::integral_constant::operator()201304L<type_traits>(C++14)N3545
__cpp_lib_interpolatestd::lerp, std::midpoint201902L<cmath> <numeric>(C++20)P0811R3
__cpp_lib_invokestd::invoke201411L<functional>(C++17)N4169
__cpp_lib_invoke_rstd::invoke_r202106L<functional>(C++23)P2136R3
__cpp_lib_ios_noreplace为 fstreams 支持独占模式202207L<ios>(C++23)P2467R1
__cpp_lib_is_aggregatestd::is_aggregate201703L<type_traits>(C++17)LWG2911
__cpp_lib_is_constant_evaluatedstd::is_constant_evaluated201811L<type_traits>(C++20)P0595R2
__cpp_lib_is_finalstd::is_final201402L<type_traits>(C++14)LWG2112
__cpp_lib_is_implicit_lifetimestd::is_implicit_lifetime202302L<type_traits>(C++23)P2674R1
__cpp_lib_is_invocablestd::is_invocable, std::invoke_result201703L<type_traits>(C++17)P0604R0
__cpp_lib_is_layout_compatiblestd::is_layout_compatible201907L<type_traits>(C++20)P0466R5
__cpp_lib_is_nothrow_convertiblestd::is_nothrow_convertible201806L<type_traits>(C++20)P0758R1 LWG3356
__cpp_lib_is_null_pointerstd::is_null_pointer201309L<type_traits>(C++14)LWG2247
__cpp_lib_is_pointer_interconvertible指针互换性特征:std::is_pointer_interconvertible_with_class, std::is_pointer_interconvertible_base_of201907L<type_traits>(C++20)P0466R5
__cpp_lib_is_scoped_enumstd::is_scoped_enum202011L<type_traits>(C++23)P1048R1
__cpp_lib_is_swappablenothrow-swappable 特征201603L<type_traits>(C++17)P0185R1
__cpp_lib_jthread停止令牌joining 线程201911L<stop_token> <thread>(C++20)P0660R10 P1869R1
__cpp_lib_latchstd::latch201907L<latch>(C++20)P1135R6
__cpp_lib_launder核心问题 1776:包含引用成员的类对象的替换 (std::launder)201606L<new>(C++17)P0137R1
__cpp_lib_list_move_return_type更改 std::forward_list 和 std::list 的 move()move_if()unique() 成员的返回类型201806L<forward_list > <list>(C++20)P0646R1
__cpp_lib_logical_traits类型特征的逻辑运算201510L<type_traits>(C++17)P0013R1
__cpp_lib_make_from_tuplestd::make_from_tuple()201606L<tuple>(C++17)P0209R2
__cpp_lib_make_reverse_iteratorstd::make_reverse_iterator201402L<iterator>(C++14)LWG2285
__cpp_lib_make_uniquestd::make_unique201304L<memory>(C++14)N3656
__cpp_lib_map_try_emplacestd::map::try_emplace, std::map::insert_or_assign201411L<map>(C++17)N4279
__cpp_lib_math_constants数学常量201907L<numbers>(C++20)P0631R8
__cpp_lib_math_special_functionsC++17 的数学特殊函数201603L<cmath>(C++17)P0226R1
__cpp_lib_mdspanstd::mdspan202207L<mdspan>(C++23)P0009R18 P2599R2 P2604R0 P2613R1
__cpp_lib_memory_resourcestd::pmr::memory_resource201603L<memory_resource>(C++17)P0220R1
__cpp_lib_modules标准库模块 stdd 和 std.compat202207L(C++23)P2465R3
__cpp_lib_move_iterator_concept使 std::move_iterator<T*> 成为随机访问迭代器202207L<iterator>(C++23)P2520R0
__cpp_lib_move_only_functionstd::move_only_function202110L<functional>(C++23)P0288R9
__cpp_lib_node_extract拼接映射和集合 (std::map::extract, std::map::merge, std::map::insert(node_type) 等)201606L<map> <set> <unordered_map> <unordered_set>(C++17)P0083R3
__cpp_lib_nonmember_container_accessstd::size(), std::data() 和 std::empty()201411L<iterator> <array> <deque> <forward_list > <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector>(C++17)N4280
__cpp_lib_not_fnstd::not_fn()201603L<functional>(C++17)P0005R4
__cpp_lib_null_iterators空 LegacyForwardIterators201304L<iterator>(C++14)N3644
__cpp_lib_optionalstd::optional201606L<optional>(C++17)P0220R1 P0032R3 P0307R2
__cpp_lib_optional完全 constexpr std::optional202106L<optional>(C++20) (DR)P2231R1
__cpp_lib_optionalstd::optional 中的单子操作202110L<optional>(C++23)P0798R8 LWG3621
__cpp_lib_out_ptrstd::out_ptr, std::inout_ptr202106L<memory>(C++23)P1132R7
__cpp_lib_parallel_algorithm并行算法201603L<algorithm> <numeric>(C++17)P0024R2
__cpp_lib_polymorphic_allocatorstd::pmr::polymorphic_allocator<> 作为词汇类型201902L<memory_resource>(C++20)P0339R6 LWG3437
__cpp_lib_print格式化输出202207L<ostream> <print>(C++23)P2093R14
__cpp_lib_quoted_string_iostd::quoted201304L<iomanip>(C++14)N3654
__cpp_lib_rangesRanges 库约束算法201911L<algorithm> <functional> <iterator> <memory> <ranges>(C++20)P0896R4 P1035R7 P1716R3
__cpp_lib_ranges非默认可初始化的视图202106L(C++20) (DR)P2325R3
__cpp_lib_ranges带有所有权的视图202110L(C++20) (DR)P2415R2
__cpp_lib_rangesstd::ranges::range_adaptor_closure202202L(C++23)P2387R3
__cpp_lib_ranges放宽范围适配器以允许仅移动类型202207L(C++23)P2494R2
__cpp_lib_ranges移除 ranges::begin, ranges::end, ranges::rbegin, ranges::rend, 和 ranges::size 中的“毒丸”重载202211L(C++23)P2602R2
__cpp_lib_ranges放宽 ranges 以允许某些投影202302L(C++23)P2609R3
__cpp_lib_ranges_as_conststd::const_iterator, std::ranges::as_const_view202207L<ranges>(C++23)P2278R4
__cpp_lib_ranges_as_rvaluestd::ranges::as_rvalue_view202207L<ranges>(C++23)P2446R2
__cpp_lib_ranges_cartesian_productstd::ranges::cartesian_product_view202207L<ranges>(C++23)P2374R4 P2540R1
__cpp_lib_ranges_chunkstd::ranges::chunk_view202202L<ranges>(C++23)P2442R1
__cpp_lib_ranges_chunk_bystd::ranges::chunk_by_view202202L<ranges>(C++23)P2443R1
__cpp_lib_ranges_containsstd::ranges::contains202207L<algorithm>(C++23)P2302R4
__cpp_lib_ranges_enumeratestd::ranges::enumerate_view202302L<ranges>(C++23)P2164R9
__cpp_lib_ranges_find_laststd::find_last()202207L<algorithm>(C++23)P1223R5
__cpp_lib_ranges_foldstd::ranges fold 算法202207L<algorithm>(C++23)P2322R6
__cpp_lib_ranges_iotastd::ranges::iota202202L<numeric>(C++23)P2440R1
__cpp_lib_ranges_join_withstd::ranges::join_with_view202202L<ranges>(C++23)P2441R2
__cpp_lib_ranges_repeatstd::ranges::repeat_view202207L<ranges>(C++23)P2474R2
__cpp_lib_ranges_slidestd::ranges::slide_view202202L<ranges>(C++23)P2442R1
__cpp_lib_ranges_starts_ends_withstd::ranges::starts_with, std::ranges::ends_with202106L<algorithm>(C++23)P1659R3
__cpp_lib_ranges_stridestd::ranges::stride_view202207L<ranges>(C++23)P1899R3
__cpp_lib_ranges_to_containerstd::ranges::to202202L<ranges>(C++23)P1206R7
__cpp_lib_ranges_zipstd::ranges::zip_view, std::ranges::zip_transform_view, std::ranges::adjacent_view, std::ranges::adjacent_transform_view202110L<ranges> <tuple> <utility>(C++23)P2321R2
__cpp_lib_raw_memory_algorithms扩展内存管理工具201606L<memory>(C++17)P0040R3
__cpp_lib_reference_from_temporarystd::reference_constructs_from_temporary 和 std::reference_converts_from_temporary202202L<type_traits>(C++23)P2255R2
__cpp_lib_move_cvrefstd::move_cvref201711L<type_traits>(C++20)P0550R2
__cpp_lib_result_of_sfinaestd::result_of 和 SFINAE201210L<type_traits> <functional>(C++14)N3462
__cpp_lib_robust_nonmodifying_seq_ops使非修改序列操作更健壮 (std::mismatch、std::equal 和 std::is_permutation 的双范围重载)201304L<algorithm>(C++14)N3671
__cpp_lib_samplestd::sample201603L<algorithm>(C++17)P0220R1
__cpp_lib_scoped_lockstd::scoped_lock201703L<mutex>(C++17)P0156R2
__cpp_lib_semaphorestd::counting_semaphore, std::binary_semaphore201907L<semaphore>(C++20)P1135R6
__cpp_lib_shared_mutexstd::shared_mutex (无计时)201505L<shared_mutex>(C++17)N4508
__cpp_lib_shared_ptr_arraysstd::shared_ptr<T[]>201611L<memory>(C++17)P0497R0
__cpp_lib_shared_ptr_arraysstd::make_shared 的数组支持201707L<memory>(C++20)P0674R1
__cpp_lib_shared_ptr_weak_typeshared_ptr::weak_type201606L<memory>(C++17)P0163R0
__cpp_lib_shared_timed_mutexstd::shared_timed_mutex201402L<shared_mutex>(C++14)N3891
__cpp_lib_shiftstd::shift_left 和 std::shift_right201806L<algorithm>(C++20)P0769R2
__cpp_lib_shiftstd::ranges::shift_left 和 std::ranges::shift_right202202L<algorithm>(C++23)P2440R1
__cpp_lib_smart_ptr_for_overwrite智能指针创建和默认初始化 (std::allocate_shared_for_overwrite, std::make_shared_for_overwrite, std::make_unique_for_overwrite)202002L<memory>(C++20)P1020R1 P1973R1
__cpp_lib_source_location源代码信息捕获 (std::source_location)201907L<source_location>(C++20)P1208R6
__cpp_lib_spanstd::span202002L<span>(C++20)P0122R7 LWG3274 P1024R3 P1976R2
__cpp_lib_spanstreamstd::spanbuf, std::spanstream202106L<span_stream>(C++23)P0448R4
__cpp_lib_ssizestd::ssize 和无符号 std::span::size201902L<iterator>(C++20)P1227R2
__cpp_lib_stacktrace堆栈跟踪库202011L<stacktrace>(C++23)P0881R7
__cpp_lib_start_lifetime_as显式生命周期管理 (std::start_lifetime_as)202207L<memory>(C++23)P2590R2
__cpp_lib_starts_ends_with字符串前缀和后缀检查 (std::string 和 std::string_view 的 [starts_with()] 和 [ends_with()])201711L<string> <string_view>(C++20)P0457R2
__cpp_lib_stdatomic_hC 原子操作的兼容头文件202011L<stdatomic.h>(C++23)P0943R6
__cpp_lib_string_containsstd::basic_string 和 std::basic_string_view 的 contains 函数202011L<string> <string_view>(C++23)P1679R3
__cpp_lib_string_resize_and_overwritestd::basic_string::resize_and_overwrite202110L<string>(C++23)P1072R10
__cpp_lib_string_udls字符串类型的用户定义字面量201304L<string>(C++14)N3642
__cpp_lib_string_viewstd::string_view201606L<string> <string_view>(C++17)P0220R1 P0254R2
__cpp_lib_string_viewConstexprIterator201803L<string> <string_view>(C++20)P0858R0 LWG3257
__cpp_lib_syncbuf同步缓冲输出流 (std::syncbuf, std::osyncstream) 和操纵符201803L<syncstream>(C++20)P0053R7 P0753R2
__cpp_lib_three_way_comparison三向比较 (库支持); 将三向比较添加到库中201907L<compare>(C++20)P0768R1 P1614R2
__cpp_lib_to_address将指针转换为原始指针的实用程序 (std::to_address)201711L<memory>(C++20)P0653R2
__cpp_lib_to_arraystd::to_array201907L<array>(C++20)P0325R4
__cpp_lib_to_chars基本字符串转换 (std::to_chars, std::from_chars)201611L<charconv>(C++17)P0067R5 P0682R1 LWG3137
__cpp_lib_to_underlyingstd::to_underlying202102L<utility>(C++23)P1682R2
__cpp_lib_transformation_trait_aliasesTransformationTraits 的别名模板201304L<type_traits>(C++14)N3655
__cpp_lib_transparent_operators透明运算符函数对象 (std::less<> 等)201210L<functional>(C++14)N3421
__cpp_lib_transparent_operators透明 std::owner_less (std::owner_less<void>)201510L<memory> <functional>(C++17)P0074R0
__cpp_lib_tuple_element_tstd::tuple_element_t201402L<tuple>(C++14)N3887
__cpp_lib_tuple_likestd::tuple 和类 tuple 对象 (std::pair, std::array, std::subrange) 之间的兼容性202207L<map> <tuple> <unordered_map> <utility>(C++23)P2165R4
__cpp_lib_tuples_by_type通过类型寻址元组201304L<tuple> <utility>(C++14)N3670
__cpp_lib_type_identitystd::type_identity201806L<type_traits>(C++20)P0887R1
__cpp_lib_type_trait_variable_templates类型特征变量模板 (std::is_void_v, 等)201510L<type_traits>(C++17)P0006R0
__cpp_lib_uncaught_exceptionsstd::uncaught_exceptions201411L<exception>(C++17)N4259
__cpp_lib_unordered_map_try_emplacestd::unordered_map::try_emplace, std::unordered_map::insert_or_assign201411L<unordered_map>(C++17)N4279
__cpp_lib_unreachablestd::unreachable202202L<utility>(C++23)P0627R6
__cpp_lib_unwrap_refstd::unwrap_ref_decay 和 std::unwrap_reference201811L<type_traits>(C++20)P0318R1 LWG3348
__cpp_lib_variantstd::variant: C++17 的类型安全联合体201606L<variant>(C++17)P0088R3 P0393R3 P0032R3
__cpp_lib_variant派生自 std::variant 的类的 std::visit202102L<variant>(C++17) (DR)P2162R2
__cpp_lib_variant完全 constexpr std::variant202106L<variant>(C++20) (DR)P2231R1
__cpp_lib_void_tstd::void_t201411L<type_traits>(C++17)N3911

示例

正常用法

#ifdef __has_include                           // Check if __has_include is present
# if __has_include(<optional>) // Check for a standard library
# include <optional>
# elif __has_include(<experimental/optional>) // Check for an experimental version
# include <experimental/optional>
# elif __has_include(<boost/optional.hpp>) // Try withan external library
# include <boost/optional.hpp>
# else // Not found at all
# error "Missing <optional>"
# endif
#endif

#ifdef __has_cpp_attribute // Check if __has_cpp_attribute is present
# if __has_cpp_attribute(deprecated) // Check for an attribute
# define DEPRECATED(msg) [[deprecated(msg)]]
# endif
#endif
#ifndef DEPRECATED
# define DEPRECATED(msg)
#endif

DEPRECATED("foo() has been deprecated") void foo();

#if __cpp_constexpr >= 201304 // Check for a specific version of a feature
# define CONSTEXPR constexpr
#else
# define CONSTEXPR inline
#endif

CONSTEXPR int bar(unsigned i)
{
#if __cpp_binary_literals // Check for the presence of a feature
unsigned mask1 = 0b11000000;
unsigned mask2 = 0b00000111;
#else
unsigned mask1 = 0xC0;
unsigned mask2 = 0x07;
#endif
if ( i & mask1 )
return 1;
if ( i & mask2 )
return 2;
return 0;
}

int main(){}

编译器功能转储

以下程序转储 C++ 编译器功能和属性。

static constexpr struct change_these_options_to_select_what_will_be_printed
{
constexpr static int longest_macro_name { 44 };
constexpr static bool titles = 1;
constexpr static bool counters = 1;
constexpr static bool attributes = 1;
constexpr static bool standard_values = 1;
constexpr static bool compiler_specific = 1;
constexpr static bool core_features = 1;
constexpr static bool lib_features = 1;
constexpr static bool supported_features = 1;
constexpr static bool unsupported_features = 1;
constexpr static bool sort_by_date = 0;
constexpr static bool separate_year_month = 1;
constexpr static bool separated_revisions = 1;
constexpr static bool latest_revisions = 1;
constexpr static bool cxx98 = 0;
constexpr static bool cxx11 = 1;
constexpr static bool cxx14 = 1;
constexpr static bool cxx17 = 1;
constexpr static bool cxx20 = 1;
constexpr static bool cxx23 = 1;
constexpr static bool cxx26 = 0;
} print;

#if __cplusplus < 201100
# error "C++11 or better is required"
#endif

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <utility>
#include <vector>

#ifdef __has_include
# if __has_include(<version>)
# include <version>
# endif
#endif

// Expect a string that starts with6-decimal-digits or with'_' (if unsupported)
#define COMPILER_VALUE_INT(n) #n [0] == '_' ? 0 : \
(#n[5] - '0') + (#n[4] - '0') * 10 + (#n[3] - '0') * 100 + \
(#n[2] - '0') * 1000 + (#n[1] - '0') * 10000 + (#n[0] - '0') * 100000
#define COMPILER_FEATURE_ENTRY(expect, name) { #name, COMPILER_VALUE_INT(name), expect },

#ifdef __has_cpp_attribute
# define COMPILER_ATTRIBUTE(expect, name) { #name, __has_cpp_attribute(name), expect },
#else
# define COMPILER_ATTRIBUTE(expect, name) { #name, COMPILER_VALUE_INT(name), expect },
#endif

#define COMPILER_SPECIFIC_STRING(value) #value
#define COMPILER_SPECIFIC_ENTRY(name) { #name, COMPILER_SPECIFIC_STRING(name) },

class CompilerFeature
{
char const* name_; long data_; long std_;
public:
constexpr CompilerFeature(char const* name, long data, long std)
: name_(name), data_(data), std_(std) {}
constexpr CompilerFeature(CompilerFeature const&) = default;
CompilerFeature& operator=(CompilerFeature const&) = default;
bool operator<(CompilerFeature const& rhs) const
{ return std::strcmp(name_, rhs.name_) < 0; }
bool operator==(CompilerFeature const& rhs) const
{ return std::strcmp(name_, rhs.name_) == 0; }
constexpr bool supported() const { return data_ >= std_; }
constexpr bool maybe() const { return data_ > 0; }
constexpr char const* name() const { return name_; }
constexpr long std() const { return std_; }
constexpr long data() const { return data_; }
void data(long x) { data_ = x; }
};

static /*constexpr*/ std::pair<const char*, const char*> compiler[] = {
COMPILER_SPECIFIC_ENTRY(__cplusplus) //< not compiler specific, but useful :)
COMPILER_SPECIFIC_ENTRY(__clang_major__)
COMPILER_SPECIFIC_ENTRY(__clang_minor__)
COMPILER_SPECIFIC_ENTRY(__clang_patchlevel__)
COMPILER_SPECIFIC_ENTRY(__GNUG__)
COMPILER_SPECIFIC_ENTRY(__GNUC_MINOR__)
COMPILER_SPECIFIC_ENTRY(__GNUC_PATCHLEVEL__)
// Add your favorite compiler specific macros. Undefined ones will not be printed.
};

static constexpr CompilerFeature cxx98_core[] = {
COMPILER_FEATURE_ENTRY(199711L, __cpp_exceptions)
COMPILER_FEATURE_ENTRY(199711L, __cpp_rtti)
};

static constexpr CompilerFeature cxx11_core[] = {
COMPILER_FEATURE_ENTRY(200704L, __cpp_alias_tiplates)
COMPILER_FEATURE_ENTRY(200809L, __cpp_attributes)
COMPILER_FEATURE_ENTRY(200704L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201711L, __cpp_constexpr_in_decltype)
COMPILER_FEATURE_ENTRY(200707L, __cpp_decltype)
COMPILER_FEATURE_ENTRY(200604L, __cpp_delegating_constructors)
COMPILER_FEATURE_ENTRY(201511L, __cpp_inheriting_constructors)
COMPILER_FEATURE_ENTRY(200806L, __cpp_initializer_lists)
COMPILER_FEATURE_ENTRY(200907L, __cpp_lambdas)
COMPILER_FEATURE_ENTRY(200809L, __cpp_nsdmi)
COMPILER_FEATURE_ENTRY(200907L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(200710L, __cpp_raw_strings)
COMPILER_FEATURE_ENTRY(200710L, __cpp_ref_qualifiers)
COMPILER_FEATURE_ENTRY(200610L, __cpp_rvalue_references)
COMPILER_FEATURE_ENTRY(200410L, __cpp_static_assert)
COMPILER_FEATURE_ENTRY(200806L, __cpp_threadsafe_static_init)
COMPILER_FEATURE_ENTRY(200704L, __cpp_unicode_characters)
COMPILER_FEATURE_ENTRY(200710L, __cpp_unicode_literals)
COMPILER_FEATURE_ENTRY(200809L, __cpp_user_defined_literals)
COMPILER_FEATURE_ENTRY(200704L, __cpp_variadic_tiplates)
};

static constexpr CompilerFeature cxx14_core[] = {
COMPILER_FEATURE_ENTRY(201304L, __cpp_aggregate_nsdmi)
COMPILER_FEATURE_ENTRY(201304L, __cpp_binary_literals)
COMPILER_FEATURE_ENTRY(201304L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201304L, __cpp_decltype_auto)
COMPILER_FEATURE_ENTRY(201304L, __cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(201304L, __cpp_init_captures)
COMPILER_FEATURE_ENTRY(201304L, __cpp_return_type_deduction)
COMPILER_FEATURE_ENTRY(201309L, __cpp_sized_deallocation)
COMPILER_FEATURE_ENTRY(201304L, __cpp_variable_tiplates)
};
static constexpr CompilerFeature cxx14_lib[] = {
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_chrono_udls)
COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_complex_udls)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_exchange_function)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_generic_associative_lookup)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integer_sequence)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_integral_constant_callable)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_is_final)
COMPILER_FEATURE_ENTRY(201309L, __cpp_lib_is_null_pointer)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_make_reverse_iterator)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_make_unique)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_null_iterators)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_quoted_string_io)
COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_result_of_sfinae)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_robust_nonmodifying_seq_ops)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_shared_timed_mutex)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_string_udls)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_transformation_trait_aliases)
COMPILER_FEATURE_ENTRY(201210L, __cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(201402L, __cpp_lib_tuple_elient_t)
COMPILER_FEATURE_ENTRY(201304L, __cpp_lib_tuples_by_type)
};

static constexpr CompilerFeature cxx17_core[] = {
COMPILER_FEATURE_ENTRY(201603L, __cpp_aggregate_bases)
COMPILER_FEATURE_ENTRY(201606L, __cpp_aligned_new)
COMPILER_FEATURE_ENTRY(201603L, __cpp_capture_star_this)
COMPILER_FEATURE_ENTRY(201603L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201703L, __cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(201411L, __cpp_enumerator_attributes)
COMPILER_FEATURE_ENTRY(201603L, __cpp_fold_expressions)
COMPILER_FEATURE_ENTRY(201606L, __cpp_guaranteed_copy_elision)
COMPILER_FEATURE_ENTRY(201603L, __cpp_hex_float)
COMPILER_FEATURE_ENTRY(201606L, __cpp_if_constexpr)
COMPILER_FEATURE_ENTRY(201606L, __cpp_inline_variables)
COMPILER_FEATURE_ENTRY(201411L, __cpp_namespace_attributes)
COMPILER_FEATURE_ENTRY(201510L, __cpp_noexcept_function_type)
COMPILER_FEATURE_ENTRY(201411L, __cpp_nontype_tiplate_args)
COMPILER_FEATURE_ENTRY(201606L, __cpp_nontype_tiplate_parameter_auto)
COMPILER_FEATURE_ENTRY(201603L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(201411L, __cpp_static_assert)
COMPILER_FEATURE_ENTRY(201606L, __cpp_structured_bindings)
COMPILER_FEATURE_ENTRY(201611L, __cpp_tiplate_tiplate_args)
COMPILER_FEATURE_ENTRY(201611L, __cpp_variadic_using)
};
static constexpr CompilerFeature cxx17_lib[] = {
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_addressof_constexpr)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_allocator_traits_is_always_equal)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_any)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_apply)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_as_const)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_atomic_is_always_lock_free)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_bool_constant)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_boyer_moore_searcher)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_byte)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_clamp)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_enable_shared_from_this)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_execution)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_filesysti)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_gcd_lcm)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_hardware_interference_size)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_has_unique_object_representations)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_hypot)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_incomplete_container_elients)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_invoke)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_aggregate)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_is_invocable)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_is_swappable)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_launder)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_logical_traits)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_make_from_tuple)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_map_try_iplace)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_math_special_functions)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_miory_resource)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_node_extract)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_nonmiber_container_access)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_not_fn)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_parallel_algorithm)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_raw_miory_algorithms)
COMPILER_FEATURE_ENTRY(201603L, __cpp_lib_sample)
COMPILER_FEATURE_ENTRY(201703L, __cpp_lib_scoped_lock)
COMPILER_FEATURE_ENTRY(201505L, __cpp_lib_shared_mutex)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_shared_ptr_weak_type)
COMPILER_FEATURE_ENTRY(201606L, __cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(201611L, __cpp_lib_to_chars)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(201510L, __cpp_lib_type_trait_variable_tiplates)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_uncaught_exceptions)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_unordered_map_try_iplace)
COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_variant)
COMPILER_FEATURE_ENTRY(201411L, __cpp_lib_void_t)
};

static constexpr CompilerFeature cxx20_core[] = {
COMPILER_FEATURE_ENTRY(201902L, __cpp_aggregate_paren_init)
COMPILER_FEATURE_ENTRY(202207L, __cpp_char8_t)
COMPILER_FEATURE_ENTRY(202002L, __cpp_concepts)
COMPILER_FEATURE_ENTRY(201806L, __cpp_conditional_explicit)
COMPILER_FEATURE_ENTRY(202211L, __cpp_consteval)
COMPILER_FEATURE_ENTRY(202002L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(201907L, __cpp_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(201907L, __cpp_constinit)
COMPILER_FEATURE_ENTRY(201907L, __cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(201707L, __cpp_designated_initializers)
COMPILER_FEATURE_ENTRY(201707L, __cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(201902L, __cpp_impl_coroutine)
COMPILER_FEATURE_ENTRY(201806L, __cpp_impl_destroying_delete)
COMPILER_FEATURE_ENTRY(201907L, __cpp_impl_three_way_comparison)
COMPILER_FEATURE_ENTRY(201803L, __cpp_init_captures)
COMPILER_FEATURE_ENTRY(201907L, __cpp_modules)
COMPILER_FEATURE_ENTRY(201911L, __cpp_nontype_tiplate_args)
COMPILER_FEATURE_ENTRY(201907L, __cpp_using_enum)
};
static constexpr CompilerFeature cxx20_lib[] = {
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_assume_aligned)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_flag_test)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_float)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_lock_free_type_aliases)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_atomic_ref)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_atomic_shared_ptr)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_atomic_value_initialization)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_atomic_wait)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_barrier)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bind_front)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_bit_cast)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_bitops)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_bounded_array_traits)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_char8_t)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_concepts)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_constexpr_algorithms)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_constexpr_complex)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_functional)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_iterator)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_miory)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_constexpr_numeric)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_string)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_string_view)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_tuple)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_constexpr_utility)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_constexpr_vector)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_coroutine)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_destroying_delete)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_endian)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_erase_if)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_execution)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_format)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_generic_unordered_lookup)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_int_pow2)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_integer_comparison_functions)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_interpolate)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_is_constant_evaluated)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_layout_compatible)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_is_nothrow_convertible)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_is_pointer_interconvertible)
COMPILER_FEATURE_ENTRY(201911L, __cpp_lib_jthread)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_latch)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_list_riove_return_type)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_math_constants)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_polymorphic_allocator)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_riove_cvref)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_siaphore)
COMPILER_FEATURE_ENTRY(201707L, __cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_shift)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_smart_ptr_for_overwrite)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_source_location)
COMPILER_FEATURE_ENTRY(202002L, __cpp_lib_span)
COMPILER_FEATURE_ENTRY(201902L, __cpp_lib_ssize)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_starts_ends_with)
COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(201803L, __cpp_lib_syncbuf)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_three_way_comparison)
COMPILER_FEATURE_ENTRY(201711L, __cpp_lib_to_address)
COMPILER_FEATURE_ENTRY(201907L, __cpp_lib_to_array)
COMPILER_FEATURE_ENTRY(201806L, __cpp_lib_type_identity)
COMPILER_FEATURE_ENTRY(201811L, __cpp_lib_unwrap_ref)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_variant)
};

static constexpr CompilerFeature cxx23_core[] = {
COMPILER_FEATURE_ENTRY(202110L, __cpp_auto_cast)
COMPILER_FEATURE_ENTRY(202211L, __cpp_constexpr)
COMPILER_FEATURE_ENTRY(202110L, __cpp_explicit_this_parameter)
COMPILER_FEATURE_ENTRY(202106L, __cpp_if_consteval)
COMPILER_FEATURE_ENTRY(202207L, __cpp_implicit_move)
COMPILER_FEATURE_ENTRY(202211L, __cpp_multidimensional_subscript)
COMPILER_FEATURE_ENTRY(202207L, __cpp_named_character_escapes)
COMPILER_FEATURE_ENTRY(202211L, __cpp_range_based_for)
COMPILER_FEATURE_ENTRY(202011L, __cpp_size_t_suffix)
COMPILER_FEATURE_ENTRY(202207L, __cpp_static_call_operator)
};
static constexpr CompilerFeature cxx23_lib[] = {
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_adaptor_iterator_pair_constructor)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_algorithm_iterator_requirients)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_allocate_at_least)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_associative_heterogeneous_erasure)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_barrier)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_bind_back)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_byteswap)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_common_reference_wrapper)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_concepts)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_bitset)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_constexpr_charconv)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_cmath)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_constexpr_miory)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_constexpr_typeinfo)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_containers_ranges)
COMPILER_FEATURE_ENTRY(202211L, __cpp_lib_expected)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_map)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_flat_set)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_format_ranges)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_formatters)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_forward_like)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_generator)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_invoke_r)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ios_noreplace)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_is_implicit_lifetime)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_is_scoped_enum)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_mdspan)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_modules)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_move_iterator_concept)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_move_only_function)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_optional)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_out_ptr)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_print)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_const)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_as_rvalue)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_cartesian_product)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_chunk_by)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_contains)
COMPILER_FEATURE_ENTRY(202302L, __cpp_lib_ranges_enumerate)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_find_last)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_fold)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_iota)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_join_with)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_repeat)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_slide)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_ranges_starts_ends_with)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_ranges_stride)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_ranges_to_container)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_ranges_zip)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_reference_from_tiporary)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_shift)
COMPILER_FEATURE_ENTRY(202106L, __cpp_lib_spanstream)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stacktrace)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_start_lifetime_as)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_stdatomic_h)
COMPILER_FEATURE_ENTRY(202011L, __cpp_lib_string_contains)
COMPILER_FEATURE_ENTRY(202110L, __cpp_lib_string_resize_and_overwrite)
COMPILER_FEATURE_ENTRY(202102L, __cpp_lib_to_underlying)
COMPILER_FEATURE_ENTRY(202207L, __cpp_lib_tuple_like)
COMPILER_FEATURE_ENTRY(202202L, __cpp_lib_unreachable)
};

static constexpr CompilerFeature cxx26_core[] = {
//< Continue to Populate
COMPILER_FEATURE_ENTRY(202304L, __cpp_core_TODO)
};
static constexpr CompilerFeature cxx26_lib[] = {
//< Continue to Populate
COMPILER_FEATURE_ENTRY(202304L, __cpp_lib_TODO)
};

static constexpr CompilerFeature attributes[] = {
COMPILER_ATTRIBUTE(202207L, assume)
COMPILER_ATTRIBUTE(200809L, carries_dependency)
COMPILER_ATTRIBUTE(201309L, deprecated)
COMPILER_ATTRIBUTE(201603L, fallthrough)
COMPILER_ATTRIBUTE(201803L, likely)
COMPILER_ATTRIBUTE(201603L, maybe_unused)
COMPILER_ATTRIBUTE(201803L, no_unique_address)
COMPILER_ATTRIBUTE(201907L, nodiscard)
COMPILER_ATTRIBUTE(200809L, noreturn)
COMPILER_ATTRIBUTE(201803L, unlikely)
};

inline void show_compiler_specific_info()
{
std::printf("Compiler specific macros:\n");
for (auto co : compiler)
if (std::strcmp(co.first, co.second))
std::printf("%*s %s\n", -print.longest_macro_name, co.first, co.second);
}

inline void print_compiler_feature(const CompilerFeature& x)
{
if (not ((print.supported_features and x.maybe()) or
(print.unsupported_features and not x.maybe())))
return;
auto print_year_month= [](long n)
{
return std::printf("%ld%s%02ld",
n / 100, print.separate_year_month? "-" : "", n % 100);
};
std::printf("%*s ", -print.longest_macro_name, x.name());
x.maybe() ? print_year_month(x.data()) :
std::printf("------%s", print.separate_year_month? "-" : "");
if (print.standard_values)
std::printf(" %c ", (x.supported() ? (x.data() > x.std() ? '>' : '=') : '<')),
print_year_month(x.std());
std::puts("");
}

tiplate<class Container>
inline void show(char const* const title, Container const& co)
{
if (print.titles)
{
std::printf("%-s (", title);
if (print.counters)
{
std::printf("%ld/", std::count_if(std::begin(co), std::end(co),
[](CompilerFeature x)
{
return x.supported();
}));
}
std::printf("%td)\n", std::distance(std::begin(co), std::end(co)));
}
if (print.sort_by_date)
{
std::vector<CompilerFeature> v(std::begin(co), std::end(co));
std::stable_sort(v.begin(), v.end(),
[](CompilerFeature const& lhs, CompilerFeature const& rhs)
{
return lhs.data() < rhs.data();
});
std::for_each(v.cbegin(), v.cend(), print_compiler_feature);
}
else
std::for_each(std::begin(co), std::end(co), print_compiler_feature);
std::puts("");
}

inline void show_latest()
{
auto latest_rev = []() -> int
{
return print.cxx26 ? 26 : print.cxx23 ? 23 : print.cxx20 ? 20 :
print.cxx17 ? 17 : print.cxx14 ? 14 : print.cxx11 ? 11 : 98;
};
std::vector<CompilerFeature> latest;
auto add = [&latest](CompilerFeature x)
{
auto i = std::lower_bound(latest.begin(), latest.end(), x);
if (i == latest.end() or not (*i == x))
latest.insert(i, x);
else if (i->data() < x.data())
i->data(x.data());
};
char text[64];
latest.reserve(512); // max macros
if (print.core_features)
{ // preserve reverse revision insersion order!
if (print.cxx26) std::for_each(std::begin(cxx26_core), std::end(cxx26_core), add);
if (print.cxx23) std::for_each(std::begin(cxx23_core), std::end(cxx23_core), add);
if (print.cxx20) std::for_each(std::begin(cxx20_core), std::end(cxx20_core), add);
if (print.cxx17) std::for_each(std::begin(cxx17_core), std::end(cxx17_core), add);
if (print.cxx14) std::for_each(std::begin(cxx14_core), std::end(cxx14_core), add);
if (print.cxx11) std::for_each(std::begin(cxx11_core), std::end(cxx11_core), add);
if (print.cxx98) std::for_each(std::begin(cxx98_core), std::end(cxx98_core), add);
std::snprintf(text, sizeof text, "ALL CORE MACROS UP TO C++%02i", latest_rev());
show(text, latest);
}
latest.clear();
if (print.lib_features)
{ // preserve reverse revision insersion order!
if (print.cxx26) std::for_each(std::begin(cxx26_lib), std::end(cxx26_lib), add);
if (print.cxx23) std::for_each(std::begin(cxx23_lib), std::end(cxx23_lib), add);
if (print.cxx20) std::for_each(std::begin(cxx20_lib), std::end(cxx20_lib), add);
if (print.cxx17) std::for_each(std::begin(cxx17_lib), std::end(cxx17_lib), add);
if (print.cxx14) std::for_each(std::begin(cxx14_lib), std::end(cxx14_lib), add);
std::snprintf(text, sizeof text, "ALL LIB MACROS UP TO C++%02i", latest_rev());
show(text, latest);
}
}

int main()
{
if (print.separated_revisions)
{
if (print.cxx98 and print.core_features) show("C++98 CORE", cxx98_core);
if (print.cxx11 and print.core_features) show("C++11 CORE", cxx11_core);
if (print.cxx14 and print.core_features) show("C++14 CORE", cxx14_core);
if (print.cxx14 and print.lib_features ) show("C++14 LIB" , cxx14_lib);
if (print.cxx17 and print.core_features) show("C++17 CORE", cxx17_core);
if (print.cxx17 and print.lib_features ) show("C++17 LIB" , cxx17_lib);
if (print.cxx20 and print.core_features) show("C++20 CORE", cxx20_core);
if (print.cxx20 and print.lib_features ) show("C++20 LIB" , cxx20_lib);
if (print.cxx23 and print.core_features) show("C++23 CORE", cxx23_core);
if (print.cxx23 and print.lib_features ) show("C++23 LIB" , cxx23_lib);
if (print.cxx26 and print.core_features) show("C++26 CORE", cxx26_core);
if (print.cxx26 and print.lib_features ) show("C++26 LIB" , cxx26_lib);
}
if (print.latest_revisions) show_latest();
if (print.attributes) show("ATTRIBUTES", attributes);
if (print.compiler_specific) show_compiler_specific_info();
}
可能结果
C++11 CORE (20/20)
__cpp_alias_tiplates 2007-04 = 2007-04
__cpp_attributes 2008-09 = 2008-09
__cpp_constexpr 2021-10 > 2007-04
__cpp_constexpr_in_decltype 2017-11 = 2017-11
... truncated ...

C++14 CORE (9/9)
__cpp_aggregate_nsdmi 2013-04 = 2013-04
__cpp_binary_literals 2013-04 = 2013-04
__cpp_constexpr 2021-10 > 2013-04
... truncated ...

C++14 LIB (20/20)
__cpp_lib_chrono_udls 2013-04 = 2013-04
__cpp_lib_complex_udls 2013-09 = 2013-09
__cpp_lib_exchange_function 2013-04 = 2013-04
... truncated ...

C++17 CORE (20/20)
__cpp_aggregate_bases 2016-03 = 2016-03
__cpp_aligned_new 2016-06 = 2016-06
__cpp_capture_star_this 2016-03 = 2016-03
__cpp_constexpr 2021-10 > 2016-03
... truncated ...

C++17 LIB (49/49)
__cpp_lib_addressof_constexpr 2016-03 = 2016-03
__cpp_lib_allocator_traits_is_always_equal 2014-11 = 2014-11
... truncated ...

C++20 CORE (17/18)
__cpp_aggregate_paren_init 2019-02 = 2019-02
__cpp_char8_t 2018-11 = 2018-11
__cpp_concepts 2020-02 = 2020-02
... truncated ...

C++20 LIB (64/67)
__cpp_lib_array_constexpr 2018-11 = 2018-11
__cpp_lib_assume_aligned 2018-11 = 2018-11
__cpp_lib_atomic_flag_test 2019-07 = 2019-07
... truncated ...

C++23 CORE (2/11)
__cpp_char8_t 2018-11 < 2022-07
__cpp_consteval 2018-11 < 2022-11
... truncated ...

C++23 LIB (16/64)
__cpp_lib_adaptor_iterator_pair_constructor 2021-06 = 2021-06
__cpp_lib_algorithm_iterator_requirients ------- < 2022-07
__cpp_lib_allocate_at_least ------- < 2023-02
__cpp_lib_associative_heterogeneous_erasure ------- < 2021-10
__cpp_lib_barrier 2019-07 < 2023-02
... truncated ...

ALL CORE MACROS UP TO C++23 (55/65)
__cpp_aggregate_bases 2016-03 = 2016-03
__cpp_aggregate_nsdmi 2013-04 = 2013-04
__cpp_aggregate_paren_init 2019-02 = 2019-02
__cpp_alias_tiplates 2007-04 = 2007-04
... truncated ...

ALL LIB MACROS UP TO C++23 (135/185)
__cpp_lib_adaptor_iterator_pair_constructor 2021-06 = 2021-06
__cpp_lib_addressof_constexpr 2016-03 = 2016-03
__cpp_lib_algorithm_iterator_requirients ------- < 2022-07
__cpp_lib_allocate_at_least ------- < 2023-02
__cpp_lib_allocator_traits_is_always_equal 2014-11 = 2014-11
... truncated ...

ATTRIBUTES (8/10)
assume ------- < 2022-07
carries_dependency ------- < 2008-09
deprecated 2013-09 = 2013-09
fallthrough 2016-03 = 2016-03
... truncated ...

Compiler specific macros:
__cplusplus 202100L
__GNUG__ 12
__GNUC_MINOR__ 2
__GNUC_PATCHLEVEL__ 1
  1. 关于功能测试建议的官方文档
  2. 用于转储编译器功能的源代码