功能特性测试 (C++20)

来自cppreference.com
< cpp

标准中为 C++11 和之后引入的 C++ 语言和程序库的功能特性定义了一组预处理器宏。标准有意使之成为检测这些功能特性是否存在的一种简单且可移植的方式。

属性

__has_cpp_attribute( 属性记号 )

检查是否支持(宏展开后)属性记号 指名的属性

对于每个标准属性,由实现定义 __has_cpp_attribute 会展开成下表中的对应值(它是该属性被添加到工作草案中时的年份和月份)还是 0。它只会在此标准属性能够使得实现的行为遵循推荐要求时(包括发布诊断信息和改变类布局等各类行为)展开成下表中的对应值。

厂商特定的属性会以某个非零值确定。

可以在 #if #elif 的表达式中展开 __has_cpp_attribute #ifdef #ifndef #elifdef #elifndef (C++23 起)defined 把它当做已定义的宏,但不能在别处使用它。

属性记号 属性 标准 标准文件
assume [[assume]] 202207L (C++23) P1774R8
carries_dependency [[carries_dependency]] 200809L (C++11) N2556N2643
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 (C++17) P0189R1
201907L (C++20) P1301R4
noreturn [[noreturn]] 200809L (C++11) N2761
unlikely [[unlikely]] 201803L (C++20) P0479R5
属性总数:10

语言功能特性

下列会在每个翻译单元预定义。每个宏都会展开成对应于相应功能特性被包含到工作草案时的年份与月份的整数字面量。

当功能特性发生了显著变更时,宏会相应地更新。

宏名 功能特性 标准 标准文件
__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_binary_literals 二进制字面量 201304L (C++14) N3472
__cpp_capture_star_this [=,*this] 进行 *this 的按值 lambda 捕获 201603L (C++17) P0018R3
__cpp_char8_t char8_t 201811L (C++20) P0482R6
char8_t 兼容性和可移植性修复(允许从 UTF-8字符串文本 初始化(无符号)字符数组 202207L (C++23) P2513R4
__cpp_concepts 概念 201907L (C++20) P0734R0 P1084R2 P1452R2
有条件非重要的特殊成员函数 202002L (C++20) P0848R3
__cpp_conditional_explicit explicit(bool) 201806L (C++20) P0892R2
__cpp_consteval 立即函数 201811L (C++20) P1073R3
使 consteval 向上传播 202211L (C++23) P2564R3
__cpp_constexpr constexpr 200704L (C++11) N2235
解除 constexpr 上的限制const constexpr 方法 201304L (C++14) N3652
Constexpr lambda 201603L (C++17) P0170R1
constexpr 函数中的非重要默认初始化汇编声明 201907L (C++20) P1064R0 P1002R1 P1327R1 P1330R0 P1331R2 P1668R1
在不断评估中更改工会的活动成员 202002L (C++20) P1330R0
constexpr 函数中的非字面变量、标签及 goto 语句 202110L (C++23) P2242R3
解除对 constexpr 函数和函数模板的一些限制 202207L (C++23) P2448R2
在 constexpr 函数中允许静态 constexpr 变量 202211L (C++23) P2647R1
void*constexpr的强制转换 202306L (C++26) P2738R1
__cpp_constexpr_dynamic_alloc constexpr 函数中的动态存储期操作 201907L (C++20) P0784R7
__cpp_constexpr_in_decltype 在为常量求值所需要时生成函数和变量的定义 201711L (C++11)(DR) P0859R0
__cpp_constinit constinit 201907L (C++20) P1143R2
__cpp_decltype decltype 200707L (C++11) N2343
__cpp_decltype_auto 常规函数的返回类型推导 201304L (C++14)
__cpp_deduction_guides 类模板的模板实参推导 201703L (C++17)
聚合体与别名的 CTAD 201907L (C++20)
__cpp_delegating_constructors 委托构造函数 200604L (C++11)
__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
泛型 lambda 的显式模板形参列表 201707L (C++20) P0428R2
__cpp_guaranteed_copy_elision 通过简化值类别保证复制消除 201606L (C++17) P0135R1
__cpp_hex_float 十六进制浮点字面量 201603L (C++17) P0245R1
__cpp_if_consteval consteval if 202106L (C++23) P1938R3
__cpp_if_constexpr constexpr if 201606L (C++17) P0292R2
__cpp_impl_coroutine 协程(编译器支持) 201902L (C++20) P0912R5 LWG3393
__cpp_impl_destroying_delete Destroying operator delete (编译器支持) 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
重述继承构造函数 201511L (C++11)(DR) P0136R1
__cpp_init_captures Lambda 初始化捕获 201304L (C++14) N3648
Lambda 初始化捕获中的包展开 201803L (C++20) P0780R2
__cpp_initializer_lists 列表初始化std::initializer_list 200806L (C++11) N2672
__cpp_inline_variables inline 变量 201606L (C++17) P0386R2
__cpp_lambdas Lambda 表达式 200907L (C++11) N2927
__cpp_modules 模块 201907L (C++20) P1103R3 P1811R0
__cpp_multidimensional_subscript 多维下标运算符 202110L (C++23) P2128R6
static 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
非类型模板形参中的类类型与浮点类型 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
拥有相异的 begin/end 类型的基于范围的 for 循环 201603L (C++17) P0184R0
__cpp_placeholder_varibles 没有名字的占位符变量 202306L (C++26) P2169R4
__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_suffix size_t 与其有符号版本的字面量后缀 202011L (C++23) P0330R8
__cpp_sized_deallocation 具大小解分配 201309L (C++14) N3778
__cpp_static_assert static_assert 200410L (C++11) N1720
单参数的 static_assert 201411L (C++17) N3928
用户生成的static_assert消息 202306L (C++26) P2741R3
__cpp_static_call_operator static operator() 202207L (C++23) P1169R4
__cpp_structured_bindings 结构化绑定 201606L (C++17) P0217R3
__cpp_template_template_args 模板模板实参的匹配 201611L (C++17)(DR) P0522R0
__cpp_threadsafe_static_init 带并发的动态初始化和销毁 200806L (C++11) N2660
__cpp_unicode_characters 新字符类型char16_tchar32_t 200704L (C++11) N2249
__cpp_unicode_literals Unicode 字符串字面量 200710L (C++11) N2442
__cpp_user_defined_literals 用户定义字面量 200809L (C++11) N2765
__cpp_using_enum using enum 201907L (C++20) P1099R5
__cpp_variable_templates 变量模板 201304L (C++14) N3651
__cpp_variadic_templates 变参模板 200704L (C++11) N2242
__cpp_variadic_using using 声明中的包展开 201611L (C++17) P0195R2

标准库功能特性

如果包含了标头 <version> 或下表中的任意对应标头,那么下列各个宏有定义。每个宏都展开成它对应的功能特性被包含于工作草案时的年份与月份的相应整数字面量。

当功能特性发生了显著变更时,宏会相应地更新。

宏名 功能特性 头文件 标准
__cpp_lib_adaptor_iterator_pair_constructor std::stackstd::queue 的迭代器对构造函数 202106L <stack> <queue> (C++23)
__cpp_lib_addressof_constexpr constexpr std::addressof 201603L <memory> (C++17)
__cpp_lib_allocate_at_least std::allocate_at_least 202106L <memory> (C++23)
__cpp_lib_allocator_traits_is_always_equal std::allocator_traits::is_always_equal 201411L <memory> <scoped_allocator> <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++17)
__cpp_lib_any std::any 201606L <any> (C++17)
__cpp_lib_apply std::apply 201603L <tuple> (C++17)
__cpp_lib_array_constexpr std::reverse_iteratorstd::move_iteratorstd::array范围访问的 constexpr 201603L <iterator> <array> (C++17)
常量表达式迭代器 (ConstexprIterator) std::array 的 constexpr 比较;杂项 constexpr ( std::array::fill 等) 201811L <iterator> <array> (C++20)
__cpp_lib_as_const std::as_const 201510L <utility> (C++17)
__cpp_lib_associative_heterogeneous_erasure 关联容器无序关联容器中的异质擦除 202110L <map> <set> <unordered_map> <unordered_set> (C++23)
__cpp_lib_assume_aligned std::assume_aligned 201811L <memory> (C++20)
__cpp_lib_atomic_flag_test std::atomic_flag::test 201907L <atomic> (C++20)
__cpp_lib_atomic_float 浮点原子类型 201711L <atomic> (C++20)
__cpp_lib_atomic_is_always_lock_free constexpr atomic<T>::is_always_lock_free 201603L <atomic> (C++17)
__cpp_lib_atomic_lock_free_type_aliases 原子免锁整数类型( std::atomic_signed_lock_freestd::atomic_unsigned_lock_free 201907L <atomic> (C++20)
__cpp_lib_atomic_ref std::atomic_ref 201806L <atomic> (C++20)
__cpp_lib_atomic_shared_ptr std::atomic<std::shared_ptr> 201711L <memory> (C++20)
__cpp_lib_atomic_value_initialization 修正原子初始化(默认值初始化 std::atomic 201911L <atomic> <memory> (C++20)
__cpp_lib_atomic_wait 高效的 std::atomic 等待 201907L <atomic> (C++20)
__cpp_lib_barrier std::barrier 201907L <barrier> (C++20)
__cpp_lib_bind_front std::bind_front 201907L <functional> (C++20)
__cpp_lib_bit_cast std::bit_cast 201806L <bit> (C++20)
__cpp_lib_bitops 位操作 201907L <bit> (C++20)
__cpp_lib_bool_constant std::bool_constant 201505L <type_traits> (C++17)
__cpp_lib_bounded_array_traits std::is_bounded_arraystd::is_unbounded_array 201902L <type_traits> (C++20)
__cpp_lib_boyer_moore_searcher std::boyer_moore_searcher|搜索器 201603L <functional> (C++17)
__cpp_lib_byte std::byte 201603L <cstddef> (C++17)
__cpp_lib_byteswap std::byteswap 202110L <bit> (C++23)
__cpp_lib_char8_t char8_t 的库支持 201907L <atomic> <filesystem> <istream> <limits> <locale> <ostream> <string> <string_view> (C++20)
__cpp_lib_chrono std::chrono::durationstd::chrono::time_point 的舍入函数 201510L <chrono> (C++17)
std::chrono::durationstd::chrono::time_point 的所有成员函数的 constexpr 201611L <chrono> (C++17)
日历时区 201907L <chrono> (C++20)
__cpp_lib_chrono_udls 时间类型的用户定义字面量 201304L <chrono> (C++14)
__cpp_lib_clamp std::clamp 201603L <algorithm> (C++17)
__cpp_lib_complex_udls std::complex 的用户定义字面量 201309L <complex> (C++14)
__cpp_lib_concepts 标准库概念 202002L <concepts> (C++20)
__cpp_lib_constexpr_algorithms 算法的 constexpr 201806L <algorithm> (C++20)
__cpp_lib_constexpr_complex std::complex 的 constexpr 201711L <complex> (C++20)
__cpp_lib_constexpr_dynamic_alloc std::allocator 与相关工具的 201907L <memory> (C++20)
__cpp_lib_constexpr_functional 杂项 constexpr ( std::default_searcher ); constexpr INVOKE 201907L <functional> (C++20)
__cpp_lib_constexpr_iterator 杂项 constexpr ( std::insert_iterator 等) 201811L <iterator> (C++20)
__cpp_lib_constexpr_memory std::pointer_traits 中的 constexpr 201811L <memory> (C++20)
__cpp_lib_constexpr_numeric <numeric> 算法的 constexpr 201911L <numeric> (C++20)
__cpp_lib_constexpr_string std::string 的 constexpr 201907L <string> (C++20)
__cpp_lib_constexpr_string_view 杂项 constexpr ( std::string_view::copy 201811L <string_view> (C++20)
__cpp_lib_constexpr_tuple 杂项 constexpr ( std::tuple::operator= 等) 201811L <tuple> (C++20)
__cpp_lib_constexpr_typeinfo std::type_info::operator== 的 constexpr 202106L <typeinfo> (C++23)
__cpp_lib_constexpr_utility 杂项 constexpr ( std::pair::operator= 等) 201811L <utility> (C++20)
__cpp_lib_constexpr_vector std::vector 的 constexpr 201907L <vector> (C++20)
__cpp_lib_coroutine 协程(库支持) 201902L <coroutine> (C++20)
__cpp_lib_destroying_delete 销毁的 operator delete (库支持) 201806L <new> (C++20)
__cpp_lib_enable_shared_from_this 再次启用 shared_from_this 201603L <memory> (C++17)
__cpp_lib_endian std::endian 201907L <bit> (C++20)
__cpp_lib_erase_if 统一容器擦除 202002L <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++20)
__cpp_lib_exchange_function std::exchange 201304L <utility> (C++14)
__cpp_lib_execution 执行策略 201603L <execution> (C++17)
std::execution::unsequenced_policy 201902L <execution> (C++20)
__cpp_lib_filesystem 文件系统库 201703L <filesystem> (C++17)
__cpp_lib_format 文本格式化 201907L <format> (C++20)
编译时格式字符串检查;减少 std::vformat_to 的参数化 202106L <format> (C++23)
修复 chrono 格式化器中的本地环境处理;格式化参数中使用转发引用 202110L <format> (C++23)
__cpp_lib_gcd_lcm std::gcdstd::lcm 201606L <numeric> (C++17)
__cpp_lib_generic_associative_lookup 关联容器中的异质比较查找 201304L <map> <set> (C++14)
__cpp_lib_generic_unordered_lookup 无序关联容器中的异质比较查找 201811L <unordered_map> <unordered_set> (C++20)
__cpp_lib_hardware_interference_size constexpr std::hardware_{constructive, destructive}_interference_size 201703L <new> (C++17)
__cpp_lib_has_unique_object_representations std::has_unique_object_representations 201606L <type_traits> (C++17)
__cpp_lib_hypot std::hypot 的 3 参数重载 201603L <cmath> (C++17)
__cpp_lib_incomplete_container_elements 标准容器的最小不完整类型支持 201505L <forward_list> <list> <vector> (C++17)
__cpp_lib_int_pow2 整数的 2 的幂运算std::has_single_bitstd::bit_ceilstd::bit_floorstd::bit_length 202002L <bit> (C++20)
__cpp_lib_integer_comparison_functions 整数比较函数 202002L <utility> (C++20)
__cpp_lib_integer_sequence 编译时整数序列 201304L <utility> (C++14)
__cpp_lib_integral_constant_callable std::integral_constant::operator() 201304L <type_traits> (C++14)
__cpp_lib_interpolate std::lerpstd::midpoint 201902L <cmath> <numeric> (C++20)
__cpp_lib_invoke std::invoke() 201411L <functional> (C++17)
__cpp_lib_invoke_r std::invoke_r 202106L <functional> (C++23)
__cpp_lib_is_aggregate std::is_aggregate 201703L <type_traits> (C++17)
__cpp_lib_is_constant_evaluated std::is_constant_evaluated 201811L <type_traits> (C++20)
__cpp_lib_is_final std::is_final 201402L <type_traits> (C++14)
__cpp_lib_is_invocable std::is_invocablestd::invoke_result 201703L <type_traits> (C++17)
__cpp_lib_is_layout_compatible std::is_layout_compatible 201907L <type_traits> (C++20)
__cpp_lib_is_nothrow_convertible std::is_nothrow_convertible 201806L <type_traits> (C++20)
__cpp_lib_is_null_pointer std::is_null_pointer 201309L <type_traits> (C++14)
__cpp_lib_is_pointer_interconvertible 指针可互转换特征 201907L <type_traits> (C++20)
__cpp_lib_is_scoped_enum std::is_scoped_enum 202011L <type_traits> (C++23)
__cpp_lib_is_swappable [nothrow-]swappable 特征 201603L <type_traits> (C++17)
__cpp_lib_jthread 停止记号结合线程 201911L <stop_token> <thread> (C++20)
__cpp_lib_latch std::latch 201907L <latch> (C++20)
__cpp_lib_launder 核心问题 1776 :替换含引用成员的类对象( std::launder 201606L <new> (C++17)
__cpp_lib_list_remove_return_type 更改 std::forward_liststd::list remove()remove_if()unique() 成员的返回类型 201806L <forward_list> <list> (C++20)
__cpp_lib_logical_traits 逻辑运算符类型特征 201510L <type_traits> (C++17)
__cpp_lib_make_from_tuple std::make_from_tuple() 201606L <tuple> (C++17)
__cpp_lib_make_reverse_iterator std::make_reverse_iterator 201402L <iterator> (C++14)
__cpp_lib_make_unique std::make_unique 201304L <memory> (C++14)
__cpp_lib_map_try_emplace std::map::try_emplace, std::map::insert_or_assign 201411L <map> (C++17)
__cpp_lib_math_constants 数学常数 201907L <numbers> (C++20)
__cpp_lib_math_special_functions C++17 的数学特殊函数 201603L <cmath> (C++17)
__cpp_lib_memory_resource std::pmr::memory_resource 201603L <memory_resource> (C++17)
__cpp_lib_move_only_function std::move_only_function 202110L <functional> (C++23)
__cpp_lib_node_extract 拼接 map 与 set ( std::map::extractstd::map::mergestd::map::insert(node_type) 等) 201606L <map> <set> <unordered_map> <unordered_set> (C++17)
__cpp_lib_nonmember_container_access std::size()std::data()std::empty() 201411L <iterator> <array> <deque> <forward_list> <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector> (C++17)
__cpp_lib_not_fn std::not_fn() 201603L <functional> (C++17)
__cpp_lib_null_iterators 老式向前迭代器 (LegacyForwardIterator) 201304L <iterator> (C++14)
__cpp_lib_optional std::optional 201606L <optional> (C++17)
完全 constexpr std::optional 202106L <optional> (C++23)
std::optional 中的单子操作 202110L <optional> (C++23)
__cpp_lib_out_ptr std::out_ptrstd::inout_ptr 202106L <memory> (C++23)
__cpp_lib_parallel_algorithm 并行算法 201603L <algorithm> <numeric> (C++17)
__cpp_lib_polymorphic_allocator std::pmr::polymorphic_allocator<> 作为词汇类型 201902L <memory_resource> (C++20)
__cpp_lib_quoted_string_io std::quoted 201304L <iomanip> (C++14)
__cpp_lib_ranges 范围库受约束算法 201911L <algorithm> <functional> <iterator> <memory> <ranges> (C++20)
可默认初始化视图 202106L (C++23)
所有权视图 202110L (C++23)
__cpp_lib_ranges_starts_ends_with std::ranges::starts_withstd::ranges::ends_with 202106L <algorithm> (C++23)
__cpp_lib_ranges_zip std::ranges::zip_viewstd::ranges::zip_transform_viewstd::ranges::adjacent_viewstd::ranges::adjacent_transform_view 202110L <ranges> <tuple> <utility> (C++23)
__cpp_lib_raw_memory_algorithms 扩展内存管理工具 201606L <memory> (C++17)
__cpp_lib_remove_cvref std::remove_cvref 201711L <type_traits> (C++20)
__cpp_lib_result_of_sfinae std::result_of 与 SFINAE 201210L <type_traits> <functional> (C++14)
__cpp_lib_robust_nonmodifying_seq_ops 使不修改序列的操作更稳健( std::mismatchstd::equalstd::is_permutation 的双范围重载) 201304L <algorithm> (C++14)
__cpp_lib_sample std::sample 201603L <algorithm> (C++17)
__cpp_lib_scoped_lock std::scoped_lock 201703L <mutex> (C++17)
__cpp_lib_semaphore std::counting_semaphorestd::binary_semaphore 201907L <semaphore> (C++20)
__cpp_lib_shared_mutex std::shared_mutex (无时限) 201505L <shared_mutex> (C++17)
__cpp_lib_shared_ptr_arrays std::shared_ptr<T[]> 201611L <memory> (C++17)
std::make_shared 的数组支持 201707L <memory> (C++20)
__cpp_lib_shared_ptr_weak_type shared_ptr::weak_type 201606L <memory> (C++17)
__cpp_lib_shared_timed_mutex std::shared_timed_mutex 201402L <shared_mutex> (C++14)
__cpp_lib_shift std::shift_leftstd::shift_right 201806L <algorithm> (C++20)
__cpp_lib_smart_ptr_for_overwrite 用默认初始化创建智能指针( std::allocate_shared_for_overwritestd::make_shared_for_overwritestd::make_unique_for_overwrite 201811L <memory> (C++20)
__cpp_lib_source_location 源码信息捕获( std::source_location 201907L <source_location> (C++20)
__cpp_lib_span std::span 202002L <span> (C++20)
__cpp_lib_spanstream std::spanbufstd::spanstream 202106L <spanstream> (C++23)
__cpp_lib_ssize std::ssize 与无符号的 std::span::size 201902L <iterator> (C++20)
__cpp_lib_stacktrace 栈踪库 202011L <stacktrace> (C++23)
__cpp_lib_starts_ends_with 字符串前缀与后缀检查( std::stringstd::string_viewstarts_with()ends_with() 201711L <string> <string_view> (C++20)
__cpp_lib_stdatomic_h C 原子操作的兼容头文件 202011L <stdatomic.h> (C++23)
__cpp_lib_string_contains std::basic_stringstd::basic_string_viewcontains 函数 202011L <string> <string_view> (C++23)
__cpp_lib_string_resize_and_overwrite std::basic_string::resize_and_overwrite 202110L <string> (C++23)
__cpp_lib_string_udls 字符串类型的用户定义字面量 201304L <string> (C++14)
__cpp_lib_string_view std::string_view 201606L <string> <string_view> (C++17)
常量表达式迭代器 (ConstexprIterator) 201803L <string> <string_view> (C++20)
__cpp_lib_syncbuf 同步缓冲的输出流( std::syncbufstd::osyncstream )与操纵符 201803L <syncstream> (C++20)
__cpp_lib_three_way_comparison 三路比较(库支持);添加三路比较到标准库 201907L <compare> (C++20)
__cpp_lib_to_address 转换指针为裸指针( std::to_address 201711L <memory> (C++20)
__cpp_lib_to_array std::to_array 201907L <array> (C++20)
__cpp_lib_to_chars 初等字符串转换( std::to_charsstd::from_chars 201611L <charconv> (C++17)
__cpp_lib_to_underlying std::to_underlying 202102L <utility> (C++23)
__cpp_lib_transformation_trait_aliases 变换特征的别名模板 201304L <type_traits> (C++14)
__cpp_lib_transparent_operators 通透运算符函数对象( std::less<> 等) 201210L <functional> (C++14)
通透的 std::owner_lessstd::owner_less<void> 201510L <memory> <functional> (C++17)
__cpp_lib_tuple_element_t std::tuple_element_t 201402L <tuple> (C++14)
__cpp_lib_tuples_by_type 按类型寻址 tuple 201304L <tuple> <utility> (C++14)
__cpp_lib_type_identity std::type_identity 201806L <type_traits> (C++20)
__cpp_lib_type_trait_variable_templates 类型特征变量模板( std::is_void_v 等) 201510L <type_traits> (C++17)
__cpp_lib_uncaught_exceptions std::uncaught_exceptions 201411L <exception> (C++17)
__cpp_lib_unordered_map_try_emplace std::unordered_map::try_emplacestd::unordered_map::insert_or_assign 201411L <unordered_map> (C++17)
__cpp_lib_unwrap_ref std::unwrap_ref_decaystd::unwrap_reference 201811L <type_traits> (C++20)
__cpp_lib_variant std::variant : C++17 的类型安全联合体 201606L <variant> (C++17)
std::variant 的派生类的 std::visit 202102L <variant> (C++23)
完全 constexpr std::variant 202106L <variant> (C++23)
__cpp_lib_void_t std::void_t 201411L <type_traits> (C++17)

示例

正常使用

#ifdef __has_include                           // 检查 __has_include 是否存在
#  if __has_include(<optional>)                // 检查标准库
#    include <optional>
#  elif __has_include(<experimental/optional>) // 检查实验版本
#    include <experimental/optional>
#  elif __has_include(<boost/optional.hpp>)    // 尝试外部库
#    include <boost/optional.hpp>
#  else                                        // 完全找不到
#     error "Missing <optional>"
#  endif
#endif
 
#ifdef __has_cpp_attribute                      // 检查 __has_cpp_attribute 是否存在
#  if __has_cpp_attribute(deprecated)           // 检查一个属性
#    define DEPRECATED(msg) [[deprecated(msg)]]
#  endif
#endif
#ifndef DEPRECATED
#    define DEPRECATED(msg)
#endif
 
DEPRECATED("foo() has been deprecated") void foo();
 
#if __cpp_constexpr >= 201304                   // 检查功能特性的指定版本
#  define CONSTEXPR constexpr
#else
#  define CONSTEXPR inline
#endif
 
CONSTEXPR int bar(unsigned i)
{
#ifdef __cpp_binary_literals                    // 检查功能特性是否存在
    unsigned mask1 = 0b11000000;
    unsigned mask2 = 0b00000111;
#else
    unsigned mask1 = 0xA0;
    unsigned mask2 = 0x07;
#endif
    if (i & mask1)
        return 1;
    if (i & mask2)
        return 2;
    return 0;
}
 
int main() {}

编译器功能特性输出

以下示例放出 C++ 编译器功能特性与属性。

#if __cplusplus < 201100
#  error "C++11 or better is required"
#endif
 
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <string>
 
#ifdef __has_include
# if __has_include(<version>)
#   include <version>
# endif
#endif
 
#define COMPILER_FEATURE_VALUE(value) #value
#define COMPILER_FEATURE_ENTRY(name) { #name, COMPILER_FEATURE_VALUE(name) },
 
#ifdef __has_cpp_attribute
# define COMPILER_ATTRIBUTE_VALUE_AS_STRING(s) #s
# define COMPILER_ATTRIBUTE_AS_NUMBER(x) COMPILER_ATTRIBUTE_VALUE_AS_STRING(x)
# define COMPILER_ATTRIBUTE_ENTRY(attr) \
  { #attr, COMPILER_ATTRIBUTE_AS_NUMBER(__has_cpp_attribute(attr)) },
#else
# define COMPILER_ATTRIBUTE_ENTRY(attr) { #attr, "_" },
#endif
 
// 更改这些选项以仅打印所需的信息。
static struct PrintOptions {
    constexpr static bool titles               = 1;
    constexpr static bool attributes           = 1;
    constexpr static bool general_features     = 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 sorted_by_value      = 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                = 1;
}   print;
 
struct CompilerFeature {
    CompilerFeature(const char* name = nullptr, const char* value = nullptr)
        : name(name), value(value) {}
    const char* name; const char* value;
};
 
static CompilerFeature cxx[] = {
COMPILER_FEATURE_ENTRY(__cplusplus)
COMPILER_FEATURE_ENTRY(__cpp_exceptions)
COMPILER_FEATURE_ENTRY(__cpp_rtti)
#if __GNUC__
COMPILER_FEATURE_ENTRY(__GNUC__)
COMPILER_FEATURE_ENTRY(__GNUC_MINOR__)
COMPILER_FEATURE_ENTRY(__GNUC_PATCHLEVEL__)
COMPILER_FEATURE_ENTRY(__GNUG__)
#endif
#if __clang__
COMPILER_FEATURE_ENTRY(__clang__)
COMPILER_FEATURE_ENTRY(__clang_major__)
COMPILER_FEATURE_ENTRY(__clang_minor__)
COMPILER_FEATURE_ENTRY(__clang_patchlevel__)
#endif
};
static CompilerFeature cxx11[] = {
COMPILER_FEATURE_ENTRY(__cpp_alias_templates)
COMPILER_FEATURE_ENTRY(__cpp_attributes)
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_decltype)
COMPILER_FEATURE_ENTRY(__cpp_delegating_constructors)
COMPILER_FEATURE_ENTRY(__cpp_inheriting_constructors)
COMPILER_FEATURE_ENTRY(__cpp_initializer_lists)
COMPILER_FEATURE_ENTRY(__cpp_lambdas)
COMPILER_FEATURE_ENTRY(__cpp_nsdmi)
COMPILER_FEATURE_ENTRY(__cpp_range_based_for)
COMPILER_FEATURE_ENTRY(__cpp_raw_strings)
COMPILER_FEATURE_ENTRY(__cpp_ref_qualifiers)
COMPILER_FEATURE_ENTRY(__cpp_rvalue_references)
COMPILER_FEATURE_ENTRY(__cpp_static_assert)
COMPILER_FEATURE_ENTRY(__cpp_threadsafe_static_init)
COMPILER_FEATURE_ENTRY(__cpp_unicode_characters)
COMPILER_FEATURE_ENTRY(__cpp_unicode_literals)
COMPILER_FEATURE_ENTRY(__cpp_user_defined_literals)
COMPILER_FEATURE_ENTRY(__cpp_variadic_templates)
};
static CompilerFeature cxx14[] = {
COMPILER_FEATURE_ENTRY(__cpp_aggregate_nsdmi)
COMPILER_FEATURE_ENTRY(__cpp_binary_literals)
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_decltype_auto)
COMPILER_FEATURE_ENTRY(__cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(__cpp_init_captures)
COMPILER_FEATURE_ENTRY(__cpp_return_type_deduction)
COMPILER_FEATURE_ENTRY(__cpp_sized_deallocation)
COMPILER_FEATURE_ENTRY(__cpp_variable_templates)
};
static CompilerFeature cxx14lib[] = {
COMPILER_FEATURE_ENTRY(__cpp_lib_chrono_udls)
COMPILER_FEATURE_ENTRY(__cpp_lib_complex_udls)
COMPILER_FEATURE_ENTRY(__cpp_lib_exchange_function)
COMPILER_FEATURE_ENTRY(__cpp_lib_generic_associative_lookup)
COMPILER_FEATURE_ENTRY(__cpp_lib_integer_sequence)
COMPILER_FEATURE_ENTRY(__cpp_lib_integral_constant_callable)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_final)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_null_pointer)
COMPILER_FEATURE_ENTRY(__cpp_lib_make_reverse_iterator)
COMPILER_FEATURE_ENTRY(__cpp_lib_make_unique)
COMPILER_FEATURE_ENTRY(__cpp_lib_null_iterators)
COMPILER_FEATURE_ENTRY(__cpp_lib_quoted_string_io)
COMPILER_FEATURE_ENTRY(__cpp_lib_result_of_sfinae)
COMPILER_FEATURE_ENTRY(__cpp_lib_robust_nonmodifying_seq_ops)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_timed_mutex)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_udls)
COMPILER_FEATURE_ENTRY(__cpp_lib_transformation_trait_aliases)
COMPILER_FEATURE_ENTRY(__cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(__cpp_lib_tuple_element_t)
COMPILER_FEATURE_ENTRY(__cpp_lib_tuples_by_type)
};
 
static CompilerFeature cxx17[] = {
COMPILER_FEATURE_ENTRY(__cpp_aggregate_bases)
COMPILER_FEATURE_ENTRY(__cpp_aligned_new)
COMPILER_FEATURE_ENTRY(__cpp_capture_star_this)
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(__cpp_enumerator_attributes)
COMPILER_FEATURE_ENTRY(__cpp_fold_expressions)
COMPILER_FEATURE_ENTRY(__cpp_guaranteed_copy_elision)
COMPILER_FEATURE_ENTRY(__cpp_hex_float)
COMPILER_FEATURE_ENTRY(__cpp_if_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_inheriting_constructors)
COMPILER_FEATURE_ENTRY(__cpp_inline_variables)
COMPILER_FEATURE_ENTRY(__cpp_namespace_attributes)
COMPILER_FEATURE_ENTRY(__cpp_noexcept_function_type)
COMPILER_FEATURE_ENTRY(__cpp_nontype_template_args)
COMPILER_FEATURE_ENTRY(__cpp_nontype_template_parameter_auto)
COMPILER_FEATURE_ENTRY(__cpp_range_based_for)
COMPILER_FEATURE_ENTRY(__cpp_static_assert)
COMPILER_FEATURE_ENTRY(__cpp_structured_bindings)
COMPILER_FEATURE_ENTRY(__cpp_template_template_args)
COMPILER_FEATURE_ENTRY(__cpp_variadic_using)
};
static CompilerFeature cxx17lib[] = {
COMPILER_FEATURE_ENTRY(__cpp_lib_addressof_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_lib_allocator_traits_is_always_equal)
COMPILER_FEATURE_ENTRY(__cpp_lib_any)
COMPILER_FEATURE_ENTRY(__cpp_lib_apply)
COMPILER_FEATURE_ENTRY(__cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_lib_as_const)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_is_always_lock_free)
COMPILER_FEATURE_ENTRY(__cpp_lib_bool_constant)
COMPILER_FEATURE_ENTRY(__cpp_lib_boyer_moore_searcher)
COMPILER_FEATURE_ENTRY(__cpp_lib_byte)
COMPILER_FEATURE_ENTRY(__cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(__cpp_lib_clamp)
COMPILER_FEATURE_ENTRY(__cpp_lib_enable_shared_from_this)
COMPILER_FEATURE_ENTRY(__cpp_lib_execution)
COMPILER_FEATURE_ENTRY(__cpp_lib_filesystem)
COMPILER_FEATURE_ENTRY(__cpp_lib_gcd_lcm)
COMPILER_FEATURE_ENTRY(__cpp_lib_hardware_interference_size)
COMPILER_FEATURE_ENTRY(__cpp_lib_has_unique_object_representations)
COMPILER_FEATURE_ENTRY(__cpp_lib_hypot)
COMPILER_FEATURE_ENTRY(__cpp_lib_incomplete_container_elements)
COMPILER_FEATURE_ENTRY(__cpp_lib_invoke)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_aggregate)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_invocable)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_swappable)
COMPILER_FEATURE_ENTRY(__cpp_lib_launder)
COMPILER_FEATURE_ENTRY(__cpp_lib_logical_traits)
COMPILER_FEATURE_ENTRY(__cpp_lib_make_from_tuple)
COMPILER_FEATURE_ENTRY(__cpp_lib_map_try_emplace)
COMPILER_FEATURE_ENTRY(__cpp_lib_math_special_functions)
COMPILER_FEATURE_ENTRY(__cpp_lib_memory_resource)
COMPILER_FEATURE_ENTRY(__cpp_lib_node_extract)
COMPILER_FEATURE_ENTRY(__cpp_lib_nonmember_container_access)
COMPILER_FEATURE_ENTRY(__cpp_lib_not_fn)
COMPILER_FEATURE_ENTRY(__cpp_lib_optional)
COMPILER_FEATURE_ENTRY(__cpp_lib_parallel_algorithm)
COMPILER_FEATURE_ENTRY(__cpp_lib_raw_memory_algorithms)
COMPILER_FEATURE_ENTRY(__cpp_lib_sample)
COMPILER_FEATURE_ENTRY(__cpp_lib_scoped_lock)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_mutex)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_weak_type)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(__cpp_lib_to_chars)
COMPILER_FEATURE_ENTRY(__cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(__cpp_lib_type_trait_variable_templates)
COMPILER_FEATURE_ENTRY(__cpp_lib_uncaught_exceptions)
COMPILER_FEATURE_ENTRY(__cpp_lib_unordered_map_try_emplace)
COMPILER_FEATURE_ENTRY(__cpp_lib_variant)
COMPILER_FEATURE_ENTRY(__cpp_lib_void_t)
};
 
static CompilerFeature cxx20[] = {
COMPILER_FEATURE_ENTRY(__cpp_aggregate_paren_init)
COMPILER_FEATURE_ENTRY(__cpp_char8_t)
COMPILER_FEATURE_ENTRY(__cpp_concepts)
COMPILER_FEATURE_ENTRY(__cpp_conditional_explicit)
COMPILER_FEATURE_ENTRY(__cpp_consteval)
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(__cpp_constexpr_in_decltype)
COMPILER_FEATURE_ENTRY(__cpp_constinit)
COMPILER_FEATURE_ENTRY(__cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(__cpp_designated_initializers)
COMPILER_FEATURE_ENTRY(__cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(__cpp_impl_coroutine)
COMPILER_FEATURE_ENTRY(__cpp_impl_destroying_delete)
COMPILER_FEATURE_ENTRY(__cpp_impl_three_way_comparison)
COMPILER_FEATURE_ENTRY(__cpp_init_captures)
COMPILER_FEATURE_ENTRY(__cpp_modules)
COMPILER_FEATURE_ENTRY(__cpp_nontype_template_args)
COMPILER_FEATURE_ENTRY(__cpp_using_enum)
};
static CompilerFeature cxx20lib[] = {
COMPILER_FEATURE_ENTRY(__cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_lib_assume_aligned)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_flag_test)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_float)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_lock_free_type_aliases)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_ref)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_shared_ptr)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_value_initialization)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_wait)
COMPILER_FEATURE_ENTRY(__cpp_lib_barrier)
COMPILER_FEATURE_ENTRY(__cpp_lib_bind_front)
COMPILER_FEATURE_ENTRY(__cpp_lib_bit_cast)
COMPILER_FEATURE_ENTRY(__cpp_lib_bitops)
COMPILER_FEATURE_ENTRY(__cpp_lib_bounded_array_traits)
COMPILER_FEATURE_ENTRY(__cpp_lib_char8_t)
COMPILER_FEATURE_ENTRY(__cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(__cpp_lib_concepts)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_algorithms)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_complex)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_functional)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_iterator)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_memory)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_numeric)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_string)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_string_view)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_tuple)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_utility)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_vector)
COMPILER_FEATURE_ENTRY(__cpp_lib_coroutine)
COMPILER_FEATURE_ENTRY(__cpp_lib_destroying_delete)
COMPILER_FEATURE_ENTRY(__cpp_lib_endian)
COMPILER_FEATURE_ENTRY(__cpp_lib_erase_if)
COMPILER_FEATURE_ENTRY(__cpp_lib_execution)
COMPILER_FEATURE_ENTRY(__cpp_lib_format)
COMPILER_FEATURE_ENTRY(__cpp_lib_generic_unordered_lookup)
COMPILER_FEATURE_ENTRY(__cpp_lib_int_pow2)
COMPILER_FEATURE_ENTRY(__cpp_lib_integer_comparison_functions)
COMPILER_FEATURE_ENTRY(__cpp_lib_interpolate)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_constant_evaluated)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_layout_compatible)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_nothrow_convertible)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_pointer_interconvertible)
COMPILER_FEATURE_ENTRY(__cpp_lib_jthread)
COMPILER_FEATURE_ENTRY(__cpp_lib_latch)
COMPILER_FEATURE_ENTRY(__cpp_lib_list_remove_return_type)
COMPILER_FEATURE_ENTRY(__cpp_lib_math_constants)
COMPILER_FEATURE_ENTRY(__cpp_lib_polymorphic_allocator)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(__cpp_lib_remove_cvref)
COMPILER_FEATURE_ENTRY(__cpp_lib_semaphore)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(__cpp_lib_shift)
COMPILER_FEATURE_ENTRY(__cpp_lib_smart_ptr_for_overwrite)
COMPILER_FEATURE_ENTRY(__cpp_lib_source_location)
COMPILER_FEATURE_ENTRY(__cpp_lib_span)
COMPILER_FEATURE_ENTRY(__cpp_lib_ssize)
COMPILER_FEATURE_ENTRY(__cpp_lib_starts_ends_with)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(__cpp_lib_syncbuf)
COMPILER_FEATURE_ENTRY(__cpp_lib_three_way_comparison)
COMPILER_FEATURE_ENTRY(__cpp_lib_to_address)
COMPILER_FEATURE_ENTRY(__cpp_lib_to_array)
COMPILER_FEATURE_ENTRY(__cpp_lib_type_identity)
COMPILER_FEATURE_ENTRY(__cpp_lib_unwrap_ref)
};
 
static CompilerFeature cxx23[] = {
//< 继续填充
COMPILER_FEATURE_ENTRY(__cpp_if_consteval)
COMPILER_FEATURE_ENTRY(__cpp_size_t_suffix)
};
static CompilerFeature cxx23lib[] = {
//< 继续填充
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_typeinfo)
COMPILER_FEATURE_ENTRY(__cpp_lib_invoke_r)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_scoped_enum)
COMPILER_FEATURE_ENTRY(__cpp_lib_stacktrace)
COMPILER_FEATURE_ENTRY(__cpp_lib_stdatomic_h)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_contains)
COMPILER_FEATURE_ENTRY(__cpp_lib_to_underlying)
COMPILER_FEATURE_ENTRY(__cpp_lib_variant)
};
 static CompilerFeature cxx26[] = {
//< 继续填充
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_static_assert)
COMPILER_FEATURE_ENTRY(__cpp_placeholder_variables)
};
static CompilerFeature cxx26lib[] = {
//< 继续填充
COMPILER_FEATURE_ENTRY(__cplusplus)
};
 
static CompilerFeature attributes[] = {
COMPILER_ATTRIBUTE_ENTRY(carries_dependency)
COMPILER_ATTRIBUTE_ENTRY(deprecated)
COMPILER_ATTRIBUTE_ENTRY(fallthrough)
COMPILER_ATTRIBUTE_ENTRY(likely)
COMPILER_ATTRIBUTE_ENTRY(maybe_unused)
COMPILER_ATTRIBUTE_ENTRY(nodiscard)
COMPILER_ATTRIBUTE_ENTRY(noreturn)
COMPILER_ATTRIBUTE_ENTRY(no_unique_address)
COMPILER_ATTRIBUTE_ENTRY(unlikely)
};
 
constexpr bool is_feature_supported(const CompilerFeature& x) {
    return x.value[0] != '_' && x.value[0] != '0' ;
}
 
inline void print_compiler_feature(const CompilerFeature& x) {
    constexpr static int max_name_length = 44; //< Update if necessary
    std::string value{ is_feature_supported(x) ? x.value : "------" };
    if (value.back() == 'L') value.pop_back(); //~ 201603L -> 201603
    // value.insert(4, 1, '-'); //~ 201603 -> 2016-03
    if ( (print.supported_features && is_feature_supported(x))
        or (print.unsupported_features && !is_feature_supported(x))) {
            std::cout << std::left << std::setw(max_name_length)
                      << x.name << " " << value << std::endl;
    }
}
 
template<std::size_t N>
inline void show(char const* title, CompilerFeature (&features)[N]) {
    if (print.titles) {
        std::cout << std::left << title << std::endl;
    }
    if (print.sorted_by_value) {
        std::sort(std::begin(features), std::end(features),
            [](CompilerFeature const& lhs, CompilerFeature const& rhs) {
                return std::strcmp(lhs.value, rhs.value) < 0;
            });
    }
    for (const CompilerFeature& x : features) {
        print_compiler_feature(x);
    }
    std::cout << std::endl;
}
 
int main() {
    if (print.general_features) show("C++ GENERAL", cxx);
    if (print.cxx11 && print.core_features) show("C++11 CORE", cxx11);
    if (print.cxx14 && print.core_features) show("C++14 CORE", cxx14);
    if (print.cxx14 && print.lib_features ) show("C++14 LIB" , cxx14lib);
    if (print.cxx17 && print.core_features) show("C++17 CORE", cxx17);
    if (print.cxx17 && print.lib_features ) show("C++17 LIB" , cxx17lib);
    if (print.cxx20 && print.core_features) show("C++20 CORE", cxx20);
    if (print.cxx20 && print.lib_features ) show("C++20 LIB" , cxx20lib);
    if (print.cxx23 && print.core_features) show("C++23 CORE", cxx23);
    if (print.cxx23 && print.lib_features ) show("C++23 LIB" , cxx23lib);
    if (print.cxx26 && print.core_features) show("C++26 CORE", cxx26);
    if (print.cxx26 && print.lib_features ) show("C++26 LIB" , cxx26lib);
    if (print.attributes) show("ATTRIBUTES", attributes);
}

可能的输出:

C++ GENERAL
__cplusplus                                  202100
__cpp_exceptions                             199711
__cpp_rtti                                   199711
__GNUC__                                     13
__GNUC_MINOR__                               1
__GNUC_PATCHLEVEL__                          ------
__GNUG__                                     13
 
C++11 CORE
__cpp_alias_templates                        200704
__cpp_attributes                             200809
__cpp_constexpr                              202211
__cpp_decltype                               200707
__cpp_delegating_constructors                200604
__cpp_inheriting_constructors                201511
__cpp_initializer_lists                      200806
__cpp_lambdas                                200907
__cpp_nsdmi                                  200809
__cpp_range_based_for                        201603
__cpp_raw_strings                            200710
__cpp_ref_qualifiers                         200710
__cpp_rvalue_references                      200610
__cpp_static_assert                          201411
__cpp_threadsafe_static_init                 200806
__cpp_unicode_characters                     201411
__cpp_unicode_literals                       200710
__cpp_user_defined_literals                  200809
__cpp_variadic_templates                     200704
 
C++14 CORE
__cpp_aggregate_nsdmi                        201304
__cpp_binary_literals                        201304
__cpp_constexpr                              202211
__cpp_decltype_auto                          201304
__cpp_generic_lambdas                        201707
__cpp_init_captures                          201803
__cpp_return_type_deduction                  201304
__cpp_sized_deallocation                     201309
__cpp_variable_templates                     201304
 
C++14 LIB
__cpp_lib_chrono_udls                        201304
__cpp_lib_complex_udls                       201309
__cpp_lib_exchange_function                  201304
__cpp_lib_generic_associative_lookup         201304
__cpp_lib_integer_sequence                   201304
__cpp_lib_integral_constant_callable         201304
__cpp_lib_is_final                           201402
__cpp_lib_is_null_pointer                    201309
__cpp_lib_make_reverse_iterator              201402
__cpp_lib_make_unique                        201304
__cpp_lib_null_iterators                     201304
__cpp_lib_quoted_string_io                   201304
__cpp_lib_result_of_sfinae                   201210
__cpp_lib_robust_nonmodifying_seq_ops        201304
__cpp_lib_shared_timed_mutex                 201402
__cpp_lib_string_udls                        201304
__cpp_lib_transformation_trait_aliases       201304
__cpp_lib_transparent_operators              201510
__cpp_lib_tuple_element_t                    201402
__cpp_lib_tuples_by_type                     201304
 
C++17 CORE
__cpp_aggregate_bases                        201603
__cpp_aligned_new                            201606
__cpp_capture_star_this                      201603
__cpp_constexpr                              202211
__cpp_deduction_guides                       201907
__cpp_enumerator_attributes                  201411
__cpp_fold_expressions                       201603
__cpp_guaranteed_copy_elision                201606
__cpp_hex_float                              201603
__cpp_if_constexpr                           201606
__cpp_inheriting_constructors                201511
__cpp_inline_variables                       201606
__cpp_namespace_attributes                   201411
__cpp_noexcept_function_type                 201510
__cpp_nontype_template_args                  201911
__cpp_nontype_template_parameter_auto        201606
__cpp_range_based_for                        201603
__cpp_static_assert                          201411
__cpp_structured_bindings                    201606
__cpp_template_template_args                 201611
__cpp_variadic_using                         201611
 
C++17 LIB
__cpp_lib_addressof_constexpr                201603
__cpp_lib_allocator_traits_is_always_equal   201411
__cpp_lib_any                                201606
__cpp_lib_apply                              201603
__cpp_lib_array_constexpr                    201811
__cpp_lib_as_const                           201510
__cpp_lib_atomic_is_always_lock_free         201603
__cpp_lib_bool_constant                      201505
__cpp_lib_boyer_moore_searcher               201603
__cpp_lib_byte                               201603
__cpp_lib_chrono                             201611
__cpp_lib_clamp                              201603
__cpp_lib_enable_shared_from_this            201603
__cpp_lib_execution                          201902
__cpp_lib_filesystem                         201703
__cpp_lib_gcd_lcm                            201606
__cpp_lib_hardware_interference_size         201703
__cpp_lib_has_unique_object_representations  201606
__cpp_lib_hypot                              201603
__cpp_lib_incomplete_container_elements      201505
__cpp_lib_invoke                             201411
__cpp_lib_is_aggregate                       201703
__cpp_lib_is_invocable                       201703
__cpp_lib_is_swappable                       201603
__cpp_lib_launder                            201606
__cpp_lib_logical_traits                     201510
__cpp_lib_make_from_tuple                    201606
__cpp_lib_map_try_emplace                    201411
__cpp_lib_math_special_functions             201603
__cpp_lib_memory_resource                    201603
__cpp_lib_node_extract                       201606
__cpp_lib_nonmember_container_access         201411
__cpp_lib_not_fn                             201603
__cpp_lib_optional                           202110
__cpp_lib_parallel_algorithm                 201603
__cpp_lib_raw_memory_algorithms              201606
__cpp_lib_sample                             201603
__cpp_lib_scoped_lock                        201703
__cpp_lib_shared_mutex                       201505
__cpp_lib_shared_ptr_arrays                  201707
__cpp_lib_shared_ptr_weak_type               201606
__cpp_lib_string_view                        201803
__cpp_lib_to_chars                           201611
__cpp_lib_transparent_operators              201510
__cpp_lib_type_trait_variable_templates      201510
__cpp_lib_uncaught_exceptions                201411
__cpp_lib_unordered_map_try_emplace          201411
__cpp_lib_variant                            202106
__cpp_lib_void_t                             201411
 
C++20 CORE
__cpp_aggregate_paren_init                   201902
__cpp_char8_t                                202207
__cpp_concepts                               202002
__cpp_conditional_explicit                   201806
__cpp_consteval                              201811
__cpp_constexpr                              202211
__cpp_constexpr_dynamic_alloc                201907
__cpp_constexpr_in_decltype                  201711
__cpp_constinit                              201907
__cpp_deduction_guides                       201907
__cpp_designated_initializers                201707
__cpp_generic_lambdas                        201707
__cpp_impl_coroutine                         201902
__cpp_impl_destroying_delete                 201806
__cpp_impl_three_way_comparison              201907
__cpp_init_captures                          201803
__cpp_modules                                ------
__cpp_nontype_template_args                  201911
__cpp_using_enum                             201907
 
C++20 LIB
__cpp_lib_array_constexpr                    201811
__cpp_lib_assume_aligned                     201811
__cpp_lib_atomic_flag_test                   201907
__cpp_lib_atomic_float                       201711
__cpp_lib_atomic_lock_free_type_aliases      201907
__cpp_lib_atomic_ref                         201806
__cpp_lib_atomic_shared_ptr                  201711
__cpp_lib_atomic_value_initialization        201911
__cpp_lib_atomic_wait                        201907
__cpp_lib_barrier                            201907
__cpp_lib_bind_front                         201907
__cpp_lib_bit_cast                           201806
__cpp_lib_bitops                             201907
__cpp_lib_bounded_array_traits               201902
__cpp_lib_char8_t                            201907
__cpp_lib_chrono                             201611
__cpp_lib_concepts                           202002
__cpp_lib_constexpr_algorithms               201806
__cpp_lib_constexpr_complex                  201711
__cpp_lib_constexpr_dynamic_alloc            201907
__cpp_lib_constexpr_functional               201907
__cpp_lib_constexpr_iterator                 201811
__cpp_lib_constexpr_memory                   202202
__cpp_lib_constexpr_numeric                  201911
__cpp_lib_constexpr_string                   201907
__cpp_lib_constexpr_string_view              201811
__cpp_lib_constexpr_tuple                    201811
__cpp_lib_constexpr_utility                  201811
__cpp_lib_constexpr_vector                   201907
__cpp_lib_coroutine                          201902
__cpp_lib_destroying_delete                  201806
__cpp_lib_endian                             201907
__cpp_lib_erase_if                           202002
__cpp_lib_execution                          201902
__cpp_lib_format                             202106
__cpp_lib_generic_unordered_lookup           201811
__cpp_lib_int_pow2                           202002
__cpp_lib_integer_comparison_functions       202002
__cpp_lib_interpolate                        201902
__cpp_lib_is_constant_evaluated              201811
__cpp_lib_is_layout_compatible               201907
__cpp_lib_is_nothrow_convertible             201806
__cpp_lib_is_pointer_interconvertible        201907
__cpp_lib_jthread                            201911
__cpp_lib_latch                              201907
__cpp_lib_list_remove_return_type            201806
__cpp_lib_math_constants                     201907
__cpp_lib_polymorphic_allocator              201902
__cpp_lib_ranges                             202202
__cpp_lib_remove_cvref                       201711
__cpp_lib_semaphore                          201907
__cpp_lib_shared_ptr_arrays                  201707
__cpp_lib_shift                              201806
__cpp_lib_smart_ptr_for_overwrite            202002
__cpp_lib_source_location                    201907
__cpp_lib_span                               202002
__cpp_lib_ssize                              201902
__cpp_lib_starts_ends_with                   201711
__cpp_lib_string_view                        201803
__cpp_lib_syncbuf                            201803
__cpp_lib_three_way_comparison               201907
__cpp_lib_to_address                         201711
__cpp_lib_to_array                           201907
__cpp_lib_type_identity                      201806
__cpp_lib_unwrap_ref                         201811
 
C++23 CORE
__cpp_if_consteval                           202106
__cpp_size_t_suffix                          202011
 
C++23 LIB
__cpp_lib_constexpr_typeinfo                 202106
__cpp_lib_invoke_r                           202106
__cpp_lib_is_scoped_enum                     202011
__cpp_lib_stacktrace                         ------
__cpp_lib_stdatomic_h                        202011
__cpp_lib_string_contains                    202011
__cpp_lib_to_underlying                      202102
__cpp_lib_variant                            202106
 
C++26 CORE
__cpp_constexpr                              202211
__cpp_static_assert                          201411
__cpp_placeholder_variables                  ------
 
C++26 LIB
__cplusplus                                  202100
 
ATTRIBUTES
carries_dependency                           ------
deprecated                                   201309
fallthrough                                  201603
likely                                       201803
maybe_unused                                 201603
nodiscard                                    201907
noreturn                                     200809
no_unique_address                            201803
unlikely                                     201803

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
P2552R3 C++20 __has_cpp_attribute 对于标准属性必须展开成非零值 可以展开成 0

参阅

库功能特性测试宏 (C++20) 在标头 <version> 定义

外部链接

1.  特性测试推荐的官方文档
2.  试出编译器特性的源码