功能特性测试 (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)
(C++26 前)
N2556
N2643
P3475R2
deprecated [[deprecated]] 201309L (C++14) N3760
fallthrough [[fallthrough]] 201603L (C++17) P0188R1
indeterminate [[indeterminate]] 202403L (C++26) P2795R5
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
给出理由的 [[nodiscard]] 201907L (C++20) P1301R4
noreturn [[noreturn]] 200809L (C++11) N2761
unlikely [[unlikely]] 201803L (C++20) P0479R5
属性总数:11

语言功能特性

下列宏可以用来检测当前实现是否实现了某个语言功能特性。它们会在每个翻译单元预定义

每个宏都会展开成对应于相应功能特性被包含到工作草案时的年份与月份的整数字面量。当功能特性发生了显著变更时,宏会相应地更新。

宏名 功能特性 标准 标准文件
__cpp_aggregate_bases 拥有基类的聚合类 201603L (C++17) P0017R1
__cpp_aggregate_nsdmi 拥有默认成员初始化器聚合类 201304L (C++14) N3653
__cpp_aggregate_paren_init 具有直接初始化形式的聚合初始化 201902L (C++20) P0960R3
__cpp_alias_templates 别名模版 200704L (C++11) N2258
__cpp_aligned_new 过对齐数据的动态内存分配 201606L (C++17) P0035R4
__cpp_attributes 属性 200809L (C++11) N2761
__cpp_auto_cast auto(x)auto{x} 202110L (C++23) P0849R8
__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)
(DR20)
P2513R4
__cpp_concepts 概念 201907L (C++20) P0734R0
P1084R2
P1452R2
按条件平凡的特殊成员函数 202002L P0848R3
P2493R0
__cpp_conditional_explicit explicit(bool) 201806L (C++20) P0892R2
__cpp_consteval 立即函数 201811L (C++20) P1073R3
使 consteval 向上传播 202211L (C++23)
(DR20)
P2564R3
__cpp_constexpr constexpr 200704L (C++11) N2235
放宽 constexpr 限制constconstexpr 方法 201304L (C++14) N3652
constexpr 的 lambda 201603L (C++17) P0170R1
在常量表达式中调用虚函数constexpr 函数中的 try,常量表达式中的 dynamic_cast 和多态 typeidconstexpr 函数中的平凡默认初始化汇编声明 201907L (C++20) P1064R0
P1002R1
P1327R1
P1331R2
P1668R1
在常量求值中改变联合体的活跃成员 202002L P1330R0
P2493R0
constexpr 函数中的非字面变量、标号和 goto 语句 202110L (C++23) P2242R3
放松对 constexpr 函数和函数模板的一些限制 202207L P2448R2
constexpr 函数中允许静态 constexpr 变量 202211L P2647R1
void* 进行 constexpr 转换:走向 constexpr 类型擦除 202306L (C++26) P2738R1
constexpr 布置 new 202406L P2747R2
__cpp_constexpr_dynamic_alloc constexpr 函数中的动态存储期操作 201907L (C++20) P0784R7
__cpp_constexpr_exceptions constexpr 异常 202411L (C++26) P3068R6
__cpp_constexpr_in_decltype 在为常量求值所需要时生成函数和变量的定义 201711L (C++20)
(DR11)
P0859R0
__cpp_constinit constinit 201907L (C++20) P1143R2
__cpp_contracts 契约 202502L (C++26) P2900R14
__cpp_decltype decltype 200707L (C++11) N2343
__cpp_decltype_auto 常规函数的返回类型推导 201304L (C++14) N3638
__cpp_deduction_guides 类模板的模板实参推导(CTAD) 201703L (C++17) P0091R3
P0512R0
P0620R0
聚合体与别名的 CTAD 201907L (C++20) P1814R0
P1816R0
__cpp_delegating_constructors 委托构造函数 200604L (C++11) N1986
__cpp_deleted_function 带消息的弃置函数定义= delete("应给出理由"); 202403L (C++26) P2573R2
__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
涉及折叠表达式约束的排序 202406L (C++26) P2963R3
__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 if consteval 202106L (C++23) P1938R3
__cpp_if_constexpr if constexpr 201606L (C++17) P0292R2
__cpp_impl_coroutine 协程(编译器支持) 201902L (C++20) P0912R5
LWG3393
__cpp_impl_destroying_delete 销毁的 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
重述继承构造函数:有关继承构造函数的信规范(DR1941 等) 201511L (C++17)
(DR11)
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 内联变量 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
静态的 operator[] 202211L 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_pack_indexing 包索引 202311L (C++26) P2662R3
__cpp_placeholder_variables 好用的无名占位符 202306L (C++26) P2169R4
__cpp_pp_embed #embed 202502L (C++26) P1967R14
__cpp_range_based_for 基于范围的 for 循环 200907L (C++11) N2930
拥有不同类型的 begin/end基于范围的 for 循环 201603L (C++17) P0184R0
基于范围的 for 循环的生存期延长 202211L (C++23) P2644R1
P2718R0
CWG2659
__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 std::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 静态的 operator() 202207L (C++23) P1169R4
__cpp_structured_bindings 结构化绑定 201606L (C++17) P0217R3
结构化绑定属性 202403L (C++26) P0609R3
结构化绑定声明为条件 202406L P0963R3
结构化绑定可以引入 202411L P1061R10
__cpp_template_parameters 概念和变量模板为模板形参 202502L (C++26) P2841R7
__cpp_template_template_args 模板模板实参的匹配 201611L (C++17) P0522R0
__cpp_threadsafe_static_init 并发的动态初始化和销毁 200806L (C++11) N2660
__cpp_trivial_relocatability 可平凡重定位性 202502L (C++26) P2786R13
__cpp_trivial_union 平凡联合体 202502L (C++26) P3074R7
__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_friend 变参友元声明 202403L (C++26) P2893R3
__cpp_variadic_templates 变参模板 200704L (C++11) N2242
__cpp_variadic_using using 声明中的包展开 201611L (C++17) P0195R2
宏的总数量:76

标准库功能特性

下列宏可以用来检测当前实现是否实现了某个标准库功能特性。和语言功能特性测试宏不同,它们不会被预定义,而是由标头 <version> 提供。

对于每个标准库功能特性宏,它也会由提供了与该宏相关的标准库组件的标头提供。完整表单列表请参阅库功能特性测试宏

每个宏都展开成它对应的功能特性被包含于工作草案时的年份与月份的相应整数字面量。当功能特性发生了显著变更时,宏会相应地更新。

宏名 功能特性 标准 标准文件
__cpp_lib_adaptor_iterator_pair_constructor std::stackstd::queue 的迭代器对构造函数 202106L (C++23) P1425R4
__cpp_lib_addressof_constexpr constexpr 的 std::addressof 201603L (C++17) LWG2296
__cpp_lib_algorithm_default_value_type 为各算法启用列表初始化 202403L (C++26) P2248R8
P3217R0
__cpp_lib_algorithm_iterator_requirements 范围迭代器作为非范围算法的输入 202207L (C++23) P2408R5
__cpp_lib_aligned_accessor std::aligned_accessor:采用过量对齐指针的 std::mdspan 访问器 202411L (C++26) P2897R7
__cpp_lib_allocate_at_least 反馈大小的分配器接口,例如:std::allocator::allocate_at_leaststd::allocator_traits::allocate_at_least 202302L (C++23) P0401R6
P2652R2
LWG3887
__cpp_lib_allocator_traits_is_always_equal std::allocator_traits::is_always_equal,清理 noexcept 201411L (C++17) N4258
__cpp_lib_any std::any 201606L (C++17) P0220R1
P0032R3
__cpp_lib_apply std::apply 201603L (C++17) P0220R1
__cpp_lib_array_constexpr constexpr 的 std::reverse_iteratorstd::move_iteratorstd::array范围访问 201603L (C++17) P0031R0
常量表达式迭代器 (ConstexprIterator) std::arrayconstexpr 比较;其他的 constexprstd::array::fill 等) 201811L (C++20) P0858R0
LWG3257
P1023R0
P1032R1
__cpp_lib_as_const std::as_const 201510L (C++17) P0007R1
__cpp_lib_associative_heterogeneous_erasure 关联容器无序关联容器的异质擦除 202110L (C++23) P2077R3
__cpp_lib_associative_heterogeneous_insertion 剩余的有序无序关联容器中剩余成员函数的异质重载 202306L (C++26) P2363R5
__cpp_lib_assume_aligned std::assume_aligned 201811L (C++20) P1007R3
__cpp_lib_atomic_flag_test std::atomic_flag::test 201907L (C++20) P1135R6
__cpp_lib_atomic_float 原子浮点类型 201711L (C++20) P0020R6
__cpp_lib_atomic_is_always_lock_free constexpr 的 std::atomic<T>::is_always_lock_free 201603L (C++17) P0152R1
__cpp_lib_atomic_lock_free_type_aliases 原子免锁整数类型(std::atomic_signed_lock_freestd::atomic_unsigned_lock_free 201907L (C++20) P1135R6
__cpp_lib_atomic_min_max 原子最大值和最小值(std::atomic::fetch_minstd::atomic::fetch_max 等) 202403L (C++26) P0493R5
__cpp_lib_atomic_ref std::atomic_ref 201806L (C++20) P0019R8
std::atomic_ref::address() 202411L (C++26) P2835R7
__cpp_lib_atomic_shared_ptr std::atomic<std::shared_ptr> 201711L (C++20) P0718R2
__cpp_lib_atomic_value_initialization 修复原子初始化(默认进行 std::atomic 值初始化) 201911L (C++20) P0883R2
__cpp_lib_atomic_wait 高效的 std::atomic 等待 201907L (C++20) P1135R6
__cpp_lib_barrier std::barrier 201907L (C++20) P1135R6
std::barrier 的阶段完成保障 202302L (C++23) P2588R3
__cpp_lib_bind_back std::bind_back 202202L (C++23) P2387R3
允许将可调用对象作为非类型模板实参传递给 std::bind_back 202306L (C++26) P2714R1
__cpp_lib_bind_front std::bind_front 201907L (C++20) P0356R5
P1651R0
允许将可调用对象作为非类型模板实参传递给 std::bind_front 202306L (C++26) P2714R1
__cpp_lib_bit_cast std::bit_cast 201806L (C++20) P0476R2
__cpp_lib_bitops 位操纵 201907L (C++20) P0553R4
__cpp_lib_bitset std::bitsetstd::string_view 接口 202306L (C++26) P2697R1
__cpp_lib_bool_constant std::bool_constant 201505L (C++17) N4389
__cpp_lib_bounded_array_traits std::is_bounded_arraystd::is_unbounded_array 201902L (C++20) P1357R1
__cpp_lib_boyer_moore_searcher 搜索器 201603L (C++17) P0220R1
__cpp_lib_byte std::byte 201603L (C++17) P0298R3
__cpp_lib_byteswap std::byteswap 202110L (C++23) P1272R4
__cpp_lib_char8_t char8_t 的库支持 201907L (C++20) P0482R6
P1423R3
__cpp_lib_chrono std::chrono::durationstd::chrono::time_point 的舍入函数 201510L (C++17) P0092R1
使得 std::chrono::durationstd::chrono::time_point 的所有成员函数 constexpr 201611L P0505R0
日历时区 201907L (C++20) P0355R7
P1466R3
std::chrono 值类的散列支持 202306L (C++26) P2592R3
__cpp_lib_chrono_udls 时间类型的用户定义字面量 201304L (C++14) N3642
__cpp_lib_clamp std::clamp 201603L (C++17) P0025R1
__cpp_lib_common_reference 使 std::reference_wrapperstd::common_reference_t 是引用类型 202302L (C++23) P2655R3
__cpp_lib_common_reference_wrapper 使 std::reference_wrapperstd::common_reference_t 是引用类型 202302L (C++23) P2655R3
__cpp_lib_complex_udls std::complex 的用户定义字面量]] 201309L (C++14) N3779
__cpp_lib_concepts 标准库概念 202002L (C++20) P0898R3
P1754R1
P1964R2
仅移动类型的 equality_comparable_withtotally_ordered_withthree_way_comparable_with 202207L (C++23) P2404R3
__cpp_lib_constexpr_algorithms constexpr 的算法 201806L (C++20) P0202R3
P0879R0
LWG3256
LWG3792
constexpr 的稳定排序 202306L (C++26) P2562R1
__cpp_lib_constexpr_atomic constexpr std::atomicstd::atomic_ref 202411L (C++26) P3309R3
__cpp_lib_constexpr_bitset 使 std::bitsetconstexpr 202207L (C++23) P2417R2
__cpp_lib_constexpr_charconv constexpr 的 std::to_charsstd::from_chars 对整数类型的重载 202207L (C++23) P2291R3
__cpp_lib_constexpr_cmath constexpr 的 <cmath><cstdlib> 中的数学函数 202202L (C++23) P0533R9
使 <cmath>constexpr 202306L (C++26) P1383R2
__cpp_lib_constexpr_complex constexpr 的 std::complex 201711L (C++20) P0415R1
使 <complex>constexpr 202306L (C++26) P1383R2
__cpp_lib_constexpr_containers constexpr 的容器和适配器 202502L (C++26) P3372R2
__cpp_lib_constexpr_dynamic_alloc constexpr 的 std::allocator 和相关工具 201907L (C++20) P0784R7
__cpp_lib_constexpr_exceptions 异常类型的 constexpr,例如 std::bad_allocstd::bad_cast 202411L (C++26) P3068R6
使异常类型更 constexpr 202502L P3378R2
__cpp_lib_constexpr_functional 其他部分的 constexprstd::default_searcher);constexprINVOKE 201907L (C++20) P1032R1
P1065R2
__cpp_lib_constexpr_inplace_vector 非平凡类型 std::inplace_vectorconstexpr 202502L (C++26) P3074R7
__cpp_lib_constexpr_iterator 其他部分的 constexprstd::insert_iterator 等) 201811L (C++20) P1032R1
__cpp_lib_constexpr_memory constexpr 的 std::pointer_traits 201811L (C++20) P1006R1
constexpr 的 std::unique_ptr 202202L (C++23) P2273R3
__cpp_lib_constexpr_new constexpr 的 布置 new 202406L (C++26) P2747R2
__cpp_lib_constexpr_numeric <numeric> 中的 constexpr 的 算法 201911L (C++20) P1645R1
__cpp_lib_constexpr_string constexpr std::char_traits 201611L (C++17) P0426R1
constexpr std::string 201907L (C++20) P0980R1
__cpp_lib_constexpr_string_view 其他部分的 constexprstd::string_view::copy 201811L (C++20) P1032R1
__cpp_lib_constexpr_tuple 其他部分的 constexprstd::tuple::operator= 等) 201811L (C++20) P1032R1
__cpp_lib_constexpr_typeinfo constexpr 的 std::type_info::operator== 202106L (C++23) P1328R1
__cpp_lib_constexpr_utility 其他部分的 constexprstd::pair::operator= 等) 201811L (C++20) P1032R1
__cpp_lib_constexpr_vector constexpr 的 std::vector 201907L (C++20) P1004R2
__cpp_lib_constrained_equality std::pairstd::tuplestd::optionalstd::variant 的受约束关系运算符 202403L (C++26) P2944R3
约束 std::expected相等性运算符 202411L P3379R0
__cpp_lib_containers_ranges 字符串和容器的范围构造和插入 202202L (C++23) P1206R7
__cpp_lib_contracts <contracts>:契约支持 202502L (C++26) P2900R14
__cpp_lib_copyable_function std::copyable_function 202306L (C++26) P2548R6
__cpp_lib_coroutine 协程(库支持) 201902L (C++20) P0912R5
LWG3393
__cpp_lib_debugging <debugging>调试支持 202311L (C++26) P2546R5
可替换 std::is_debugger_present 202403L P2810R4
__cpp_lib_destroying_delete 销毁的 operator delete(库支持) 201806L (C++20) P0722R3
__cpp_lib_enable_shared_from_this std::enable_shared_from_this::weak_from_this 201603L (C++17) P0033R1
__cpp_lib_endian std::endian 201907L (C++20) P0463R1
P1612R1
__cpp_lib_erase_if 统一的容器擦除 202002L (C++20) P1209R0
P1115R3
__cpp_lib_exchange_function std::exchange 201304L (C++14) N3668
__cpp_lib_execution 执行策略 201603L (C++17) P0024R2
std::execution::unsequenced_policy 201902L (C++20) P1001R2
__cpp_lib_expected 类模板 std::expected 202202L (C++23) P0323R12
std::expected 的单子式函数 202211L P2505R5
__cpp_lib_filesystem 文件系统库 201703L (C++17) P0218R1
P0219R1
P0392R0
P0317R1
__cpp_lib_flat_map std::flat_mapstd::flat_multimap 202207L (C++23) P0429R9
__cpp_lib_flat_set std::flat_setstd::flat_multiset 202207L (C++23) P1222R4
LWG3751
__cpp_lib_format 文本格式化 201907L (C++20) P0645R10
P1361R2
P1652R1
编译时格式字符串检查;减少 std::vformat_to 的参数化 202106L (C++23)
(DR20)
P2216R3
修复 chrono 格式化器中的本地环境处理;支持非 const 可格式化类型 202110L P2372R3
P2418R2
暴露 std::basic_format_string;澄清 chrono 类型的本地化的格式化的编码处理 202207L (C++23) P2419R2
P2508R1
格式化指针 202304L (C++26) P2510R3
格式化参数的类型检查 202305L P2757R3
visit 成员 202306L P2637R3
运行时格式字符串 202311L P2918R2
__cpp_lib_format_path std::filesystem::path 的格式化 202403L (C++26) P2845R8
__cpp_lib_format_ranges 格式化范围 202207L (C++23) P2286R8
P2585R1
LWG3750
__cpp_lib_format_uchar 修正代码单元作为整数的格式化 202311L (C++26) P2909R4
__cpp_lib_formatters 格式化 std::thread::idstd::stacktrace 202302L (C++23) P2693R1
__cpp_lib_forward_like std::forward_like 202207L (C++23) P2445R1
__cpp_lib_freestanding_algorithm <algorithm> 中的独立设施 202311L (C++26) P2407R5
__cpp_lib_freestanding_array 使 std::array 的部分功能独立 202311L (C++26) P2407R5
__cpp_lib_freestanding_char_traits 独立的 std::char_traits 202306L (C++26) P2338R4
__cpp_lib_freestanding_charconv <charconv> 中的独立设施 202306L (C++26) P2338R4
__cpp_lib_freestanding_