功能特性测试 (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