功能特性测试 (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 限制,非 const 的 constexpr 方法
|
201304L
|
(C++14) | N3652 | |
| constexpr 的 lambda | 201603L
|
(C++17) | P0170R1 | |
在常量表达式中调用虚函数;constexpr 函数中的 try 块,常量表达式中的 dynamic_cast 和多态 typeid;constexpr 函数中的平凡默认初始化和汇编声明
|
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 |