功能特性测试 (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) | 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 | (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_t 与 char32_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::stack 与 std::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_iterator 、 std::move_iterator 、 std::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_free 、 std::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_array 、 std::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::duration 与 std::chrono::time_point 的舍入函数 | 201510L | <chrono> | (C++17) |
std::chrono::duration 与 std::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::gcd、 std::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_bit 、 std::bit_ceil 、 std::bit_floor 、 std::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::lerp 与 std::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_invocable 、 std::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_list 与 std::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::extract 、 std::map::merge 、 std::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_ptr、 std::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_with、 std::ranges::ends_with | 202106L | <algorithm> | (C++23) |
__cpp_lib_ranges_zip | std::ranges::zip_view、 std::ranges::zip_transform_view、 std::ranges::adjacent_view、 std::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::mismatch 、 std::equal 及 std::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_semaphore 、 std::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_left 与 std::shift_right | 201806L | <algorithm> | (C++20) |
__cpp_lib_smart_ptr_for_overwrite | 用默认初始化创建智能指针( std::allocate_shared_for_overwrite 、 std::make_shared_for_overwrite 、 std::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::spanbuf、 std::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::string 与 std::string_view 的 starts_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_string 与 std::basic_string_view 的 contains 函数 |
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::syncbuf 、 std::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_chars 、 std::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_less ( std::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_emplace 、 std::unordered_map::insert_or_assign | 201411L | <unordered_map> | (C++17) |
__cpp_lib_unwrap_ref | std::unwrap_ref_decay 与 std::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) |
本节未完成 原因:缺少 202202L 到 202211L 共43行,详见讨论页。 |
示例
正常使用
运行此代码
#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. | 试出编译器特性的源码 |