功能测试宏和策略
文档号 | SD-FeatureTest |
日期 | 2025-06-03 |
项目 | 编程语言 C++ |
受众 | |
回复至 |
目录
1 方法解释和原理
C++ 标准化的创新步伐使得实现的长期稳定性不太可能。功能被添加到语言中是因为程序员希望使用这些功能。功能被添加到标准(工作草案)中,因为这些功能变得明确。在许多情况下,一个功能在标准正式引入它之前或之后很久就被添加到实现中。
这个过程使得想要使用某个功能的程序员很难知道它在任何给定实现中是否可用。实现很少直接从一个正式的标准修订版跳到下一个;实现过程通常以较小的步骤进行。因此,测试特定标准修订版(例如,通过检查 __cplusplus
宏的值)通常会给出错误的答案。实现者通常不希望在所有功能都实现之前就声称完全符合某个标准修订版。这使得程序员没有可移植的方法来确定哪些功能实际上对他们可用。
程序通常可以以特定于单个实现的方式确定该实现支持哪些功能;但其方法通常文档不全、随意,有时甚至复杂——尤其是当功能的可用性由调用选项控制时。在单个源代码库中为各种实现进行此确定是复杂且容易出错的。
1.1 功能测试宏之前的现状
以下代码试图确定当前实现中是否支持右值引用
#ifndef __USE_RVALUE_REFERENCES
#if (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3) || \
_MSC_VER >= 1600
#if __EDG_VERSION__ > 0
#define __USE_RVALUE_REFERENCES (__EDG_VERSION__ >= 410)
#else
#define __USE_RVALUE_REFERENCES 1
#endif
#elif __clang__
#define __USE_RVALUE_REFERENCES __has_feature(cxx_rvalue_references)
#else
#define __USE_RVALUE_REFERENCES 0
#endif
#endif
首先,检查 GNU 和 Microsoft 的版本号是否足够高。但随后检查 EDG 的版本号,因为该前端也兼容这两种编译器,并定义了宏来指示(声称的)兼容性。如果该功能未在指定的 EDG 版本中实现,则假定该功能不可用——即使 EDG 的客户有可能在 EDG 之前实现该功能。
幸运的是,Clang 有办法专门测试特定功能是否存在。但不幸的是,用于此类测试的函数调用式语法不适用于标准预处理器,因此这个出色的新功能最终为混合增加了自己的复杂性。
另请注意,此代码只是实际解决方案的开始。一个完整的解决方案需要考虑更多的编译器,以及特定于各种编译器的命令行选项设置。
1.2 建议解决方案的特点
为了保留实现者按照对自身及其客户最有意义的顺序添加功能的自由,实现者应通过添加与该功能对应的宏定义来指示每个单独功能的可用性。
重要说明:通过建议使用这些宏,WG21 并非使任何功能成为可选;相关功能测试宏的定义缺失并不意味着缺少某个功能的实现符合要求该功能的标准。但是,如果实现者和程序员遵循这些建议,则代码在实际实现之间的可移植性应该会得到改善。
首先,一个功能由WG21文件中指定它并将其引入标准工作草案的论文来标识。并非每篇论文都引入了值得功能测试宏的新功能,但每篇不仅仅是问题解决方案集合的论文都被视为候选;例外情况需要明确说明理由。
对于 C++14,功能测试宏名称通常由论文标题中的某些单词组合而成。未来,希望每篇论文都包含自己关于功能测试宏名称的建议。
为功能测试宏指定的值基于该功能被投票进入工作草案的年份和月份。如果某个功能随后发生重大变化,但仍可认为是相同的功能,则宏的值会更改以指示该功能的规范“修订级别”。然而,在大多数情况下,预期可以通过任何非零宏值的存在来确定功能的存在;例如
template<typename T>
struct use_empty_base_opt :
::integral_constant<bool,
std::is_empty<T>::value
std#if __cpp_lib_is_final
&& !std::is_final<T>::value
#endif
>
{ };
为了避免用户命名空间,语言功能宏的名称前缀为 __cpp_
;对于库功能,前缀为 __cpp_lib_
。不引入新头文件的库功能预计由实现该功能的头文件定义。
1.3 示例
根据功能可用性选择更高效的编译时实现
#if __cpp_variadic_using // can use the compile-time efficient, flat inheritance template<typename ...T> struct Callable : T... { using T::operator() ...; }; #else // fall-back to linear recursion for older compilers template<typename ...T> struct Callable; template<typename T, typename ...U> struct Callable<T, U...> : T, Callable<U...> { using T::operator(); using Callable<U...>::operator(); }; template<typename T> struct Callable<T> : T { using T::operator(); }; template<> struct Callable<> {}; #endif
同理
#if __cpp_fold_expressions template<typename... T> auto sum(T... args) { return (args + ...); } #else auto sum() { return 0; } template<typename T> auto sum(T t) { return t; } template(typename T, typename... Ts) auto sum(T t, Ts... ts) { return t + sum(ts...); } #endif
根据功能可用性选择更高效的运行时实现
void update(std::set<X>& set, const X& elem, int val) { auto pos = set.find(elem); if (pos == set.end()) return; #if __cpp_lib_node_extract auto next = std::next(pos); auto x = set.extract(pos); .value().update(val); x.insert(next, std::move(x)); set#else = *pos; X tmp = set.erase(pos); pos .update(val); tmp.insert(pos, std::move(tmp)); set#endif }
在某些情况下,功能测试宏的值可能会随着底层功能的变化而改变。为了更容易地跟踪每个功能的演变,本文档中的表格按宏名称分组——每行包含每个可能的值及其相关的提案。
根据__cpp_static_assert
有条件地实现某个功能。
#if __cpp_static_assert # if __cpp_static_assert > 201400 # define Static_Assert(cond) static_assert(cond) # else # define Static_Assert(cond) static_assert(cond, #cond) # endif # define Static_Assert_Msg(cond, msg) static_assert(cond, msg) #else # define Static_Assert(cond) # define Static_Assert_Msg(cond, msg) #endif
属性也可能随时间改变语义,这就是为什么下面描述的__has_cpp_attribute
工具评估为一个值而不是简单的1
或0
。这允许用户根据__has_cpp_attribute(nodiscard)
有条件地提供nodiscard版本
#if __has_cpp_attribute(nodiscard) >= 201907 // nodiscard has a reason and can // be applied to constructors # define NODISCARD(msg) [[nodiscard(msg)]] # define NODISCARD_CTOR(msg) [[nodiscard(msg)]] #elif __has_cpp_attribute(nodiscard) >= 201603 // nodiscard doesn't have a reason, nor can # define NODISCARD(msg) [[nodiscard]] # define NODISCARD_CTOR(msg) #else // nodiscard doesn't exist at all yet # define NODISCARD(msg) # define NODISCARD_CTOR(msg) #endif
2 建议
2.1 引言
为了提高各种C++标准部分实现之间的可移植性,WG21(ISO C++编程语言技术委员会)建议实现者和程序员遵循本文档中关于功能测试宏的指导方针。
提供新标准功能的实现者应在功能可用的相同情况下(例如,考虑相关命令行选项)定义具有推荐名称和值的宏,以指示对该功能的支持。
希望确定某个功能在实现中是否可用的程序员应根据具有推荐名称的宏的状态进行判断。(缺少经过测试的功能可能导致程序功能减少,或者相关功能可能以不同方式提供。严格依赖某个功能支持的程序可以尝试无条件使用该功能;据推测,在缺少必要支持的实现上,翻译将失败。因此,如果功能测试宏最有用的目的是在功能不可用时控制 #error 指令的包含,则认为这不足以成为该宏的理由。请注意,测试宏对某个功能的有用性与该功能本身的有用性完全无关。)
2.2 测试头文件是否存在:__has_include
C++ 程序无法直接、可靠和可移植地确定库头文件是否可用于包含。有条件地包含头文件需要使用配置宏,其设置可以通过构建时的配置测试过程(可靠,但可移植性较差)或通过其他方式(通常不可靠或不可移植)确定。
为了解决这个普遍问题,WG21 建议程序员使用 __has_include
功能。
2.2.1 语法
h-预处理-标记:
除>
之外的任何 预处理-标记
h-pp-标记:
h-预处理-标记
h-pp-标记 h-预处理-标记
has-include-表达式:
__has_include
(
头文件名)
__has_include
(
字符串字面量)
__has_include
(
<
h-pp-标记>
)
2.2.2 语义
在 has-include-expression 的第一种形式中,括号中的 header-name 标记不受宏展开的影响。只有在第一种形式不匹配时才考虑第二种和第三种形式,并且预处理标记的处理方式与正常文本中相同。
has-include-expression 只能出现在 #if
或 #elif
指令的控制常量表达式中 ([cpp.cond] 16.1)。在评估此类表达式之前,会搜索由其中包含的每个 has-include-expression 中的括号括起来的预处理标记序列标识的源文件,就像该预处理标记序列是 #include
指令中的 pp-tokens 一样,除了不执行进一步的宏展开。如果此类指令不满足 #include
指令的语法要求,则程序格式错误。如果源文件搜索成功,has-include-expression 将被 pp-number 1
替换;如果搜索失败,则替换为 pp-number 0
。
#ifdef
和 #ifndef
指令,以及定义的条件包含运算符,应将 __has_include
视为已定义宏的名称。标识符 __has_include
不应出现在本节未提及的任何上下文中。
2.2.3 示例
这演示了一种仅在可用时使用库可选功能的方法。请注意,__has_include(<optional>)
成功是不够的,因为在许多工具链上,头文件可能存在于安装中,但其内容会根据编译标志进行保护。例如,以下代码
#ifdef __has_include
#if __has_include(<optional>)
#include <optional>
::optional<int> o;
std#endif
#endif
int main(){ }
仍将无法使用 g++ -std=c++14
(使用 libstdc++)编译。
因此,我们需要这样做
#ifdef __has_include
# if __has_include(<optional>)
# include <optional>
# if __cpp_lib_optional >= 201606
# define have_optional 1
# endif
# elif __has_include(<experimental/optional>)
# include <experimental/optional>
# if __cpp_lib_experimental_optional >= 201400
# define have_optional 1
# define experimental_optional 1
# endif
#endif
#ifndef have_optional
# define have_optional 0
#endif
此外,<version>
头文件 [P0754R2] 是一个轻量级头文件,它定义了所有标准库功能测试宏。另一种实现可以是
#ifndef __has_include
# define __has_include(x) 0
#endif
#if __has_include(<version>)
# include <version>
#elif __has_include(<optional>)
# include <optional>
#endif
#if __cpp_lib_optional >= 201606
# define have_optional 1
#else
# define have_optional 0
#endif
2.3 测试属性是否存在:__has_cpp_attribute
C++ 程序无法直接、可靠且可移植地确定标准或特定于供应商的属性是否可用。测试属性支持通常需要复杂的宏逻辑,如上文针对一般语言功能所说明的那样。
为了解决这个普遍问题,WG21 建议程序员使用 __has_cpp_attribute
功能。
2.3.1 语法
has-attribute-expression:
__has_cpp_attribute
(
attribute-token)
2.3.2 语义
一个 has-attribute-expression 只能出现在 #if
或 #elif
指令的控制常量表达式中 ([cpp.cond] 16.1)。如果实现支持具有指定名称的属性,has-attribute-expression 将被替换为非零的 pp-number,否则替换为 pp-number 0
。
对于标准属性,__has_cpp_attribute
宏的值基于该属性被投票进入工作草案的年份和月份。如果属性是供应商特定的,则该值是实现定义的。然而,在大多数情况下,预期可以通过任何非零结果检测到属性的可用性。
#ifdef
和 #ifndef
指令,以及定义的条件包含运算符,应将 __has_cpp_attribute
视为已定义宏的名称。标识符 __has_cpp_attribute
不应出现在本节未提及的任何上下文中。
2.3.3 示例
这演示了仅在可用时使用属性 [[deprecated]]
的方法。
#ifndef __has_cpp_attribute
# define __has_cpp_attribute(x) 0
#endif
#if __has_cpp_attribute(deprecated)
# define ATTR_DEPRECATED(msg) [[deprecated(msg)]]
#else
# define ATTR_DEPRECATED(msg)
#endif
3 策略
SG-10 已采纳多项与我们确定和命名宏的标准实践相关的策略。
3.1 constexpr
对于语言,我们将有一个单独的 __cpp_constexpr
宏。每次我们在语言中扩展 constexpr 时,它都会被提升。对于库,我们将为重要的特殊功能添加特定的功能测试宏。否则,对于那些我们只是将 constexpr 添加到库中更多事物的情况,我们将为每个头文件提供一个专用的测试宏,并且每次更改时只提升该头文件特定的宏。该宏将命名为 __cpp_lib_constexpr_HEADER
(除了少数现有的数组和算法宏,它们的名称略有不同)。
摘自 [P1902R1]。
3.2 带有库组件的语言功能
在某些情况下,一个功能需要两个宏,一个用于语言,一个用于库。例如,除非编译器支持该功能,否则库不会定义其三向比较操作。
对于最终用户,建议他们只测试库宏,因为只有当语言宏也为真时,库宏才为真。因此,语言宏包含“impl
”以将其与预计由库设置的更通用版本区分开来。
请注意,最初 SG10 建议库版本的宏不包含通常的 _lib
部分,但 LWG 对库宏(在使用前需要头文件)不包含 _lib
的不一致性感到不适。
另请注意,SG10 最初建议核心功能测试包含 _lang
,但 LWG 希望有更清晰地暗示该宏是用于核心功能而非供最终用户使用的内容。他们建议改用 _impl
。
摘自 [P1353R0]。
4 功能测试宏表
以下是标准中的所有功能测试宏,按语言宏、属性宏和库宏划分,然后按名称排序。每个宏将包含其可能的取值列表以及在实现定义该宏为特定取值之前需要实现的论文。
请注意,同一篇论文可能会引入或更新多个功能测试宏。给定值可能需要多篇论文。论文也可能*移除*某个功能测试宏,在这种情况下,其值将被指定为 已删除。
4.1 语言功能测试宏
所有语言宏都是预定义的(即在进行检查之前无需包含任何头文件)。
在某些情况下,一个功能需要两个宏:一个用于语言,一个用于库。例如,除非编译器支持该功能,否则库不会定义其三向比较运算符。在这些情况下,建议最终用户只测试库宏。那些旨在由库检查的核心语言功能测试宏被拼写为 __cpp_impl_*
。
宏 | 值 | 论文 |
---|---|---|
__cpp_deleted_function
|
202403
|
[P2573R2] = delete(“应该有理由”); |
__cpp_aggregate_bases
|
201603
|
[P0017R1] 聚合初始化扩展 |
__cpp_aggregate_nsdmi
|
201304
|
[N3653] 成员初始化器和聚合 |
__cpp_aggregate_paren_init
|
201902
|
[P0960R3] 允许从带括号的值列表初始化聚合 |
__cpp_alias_templates
|
200704
|
[N2258] 模板别名 |
__cpp_aligned_new
|
201606
|
[P0035R4] 过对齐数据的动态内存分配 |
__cpp_attributes
|
200809
|
[N2761] C++ 中属性支持的进展(修订版 6) |
__cpp_binary_literals
|
201304
|
[N3472] C++ 核心语言中的二进制字面量 |
__cpp_capture_star_this
|
201603
|
[P0018R3] Lambda 按值捕获 *this 为 [=,*this] |
__cpp_char8_t
|
201811
|
[P0482R6] char8_t :用于 UTF-8 字符和字符串的类型(修订版 6) |
202207
|
[P2513R3] char8_t 兼容性和可移植性修复 | |
__cpp_concepts
|
201707
|
[P0734R0] 措辞文档,C++ 概念扩展 |
201811
|
[P1084R2] 今时今日的返回类型要求已不足 | |
201907
|
[P1452R2] 关于返回类型要求非统一语义的论文 | |
202002
|
[P0848R3] 有条件微不足道的特殊成员函数 | |
__cpp_conditional_explicit
|
201806
|
[P0892R2] explicit(bool) |
__cpp_consteval
|
201811
|
[P1073R3] 即时函数 |
202211
|
[P2564R3] consteval 需要向上传播 | |
__cpp_constexpr
|
200704
|
[N2235] 广义常量表达式——修订版 5 |
201304
|
[N3652] 放松 constexpr 函数的约束/constexpr 成员函数和隐式 const | |
201603
|
[P0170R1] Constexpr Lambda 的措辞 | |
201806
|
[P1064R0] 允许在常量表达式中进行虚函数调用 | |
201811
|
[P1002R1] constexpr 函数中的 try-catch 块 [P1327R1] 允许 dynamic_cast、多态 typeid 在常量表达式中 |
|
201907
|
[P1331R2] 允许在 constexpr 上下文中进行微不足道的默认初始化 [P1668R1] 通过允许 constexpr 函数中的未评估内联汇编来启用 constexpr 本征函数 |
|
202002
|
[P1330R0] 更改 union 在 constexpr 内部的活跃成员 | |
202110
|
[P2242R3] constexpr 函数中的非字面量变量(以及标签和 goto) | |
202207
|
[P2448R2] 放松某些 constexpr 限制 | |
202211
|
[P2647R1] 允许 constexpr 函数中的静态 constexpr 变量 | |
202306
|
[P2738R1] constexpr 从 void* 转换:迈向 constexpr 类型擦除 | |
202406
|
[P2747R2] constexpr placement new | |
__cpp_constexpr_dynamic_alloc
|
201907
|
[P0784R7] 更多 constexpr 容器 |
__cpp_constexpr_exceptions
|
202411
|
[P3068R6] 允许在常量求值中抛出异常 |
__cpp_constexpr_in_decltype
|
201711
|
[P0859R0] 核心问题 1581:constexpr 成员函数何时定义? |
__cpp_constinit
|
201907
|
[P1143R2] 添加 constinit 关键字 |
__cpp_contracts
|
202502
|
[P2900R14] C++ 契约 |
__cpp_decltype
|
200707
|
[N2343] Decltype(修订版 7):建议措辞 |
__cpp_decltype_auto
|
201304
|
[N3638] 普通函数的返回类型推断 |
__cpp_deduction_guides
|
201606
|
[P0091R3] 类模板的模板参数推导(修订版 6) |
201611
|
[P0512R0] 类模板参数推导杂项 NB 解决方案和问题 | |
201703
|
[P0620R0] 草拟类模板参数推导问题 | |
201907
|
[P1814R0] 别名模板的类模板参数推导措辞 [P1816R0] 聚合的类模板参数推导措辞 |
|
__cpp_delegating_constructors
|
200604
|
[N1986] 委托构造函数(修订版 3) |
__cpp_designated_initializers
|
201707
|
[P0329R4] 指定初始化措辞 |
__cpp_enumerator_attributes
|
201411
|
[N4266] 命名空间和枚举器属性 |
__cpp_exceptions
|
199711
|
异常处理 |
__cpp_explicit_this_parameter
|
202110
|
[P0847R7] 推断 this |
__cpp_fold_expressions
|
201411
|
[N4295] 折叠表达式 |
201603
|
[P0036R0] 一元折叠和空参数包(修订版 1) | |
__cpp_generic_lambdas
|
201304
|
[N3649] 泛型(多态)Lambda 表达式(修订版 3) |
201707
|
[P0428R2] 泛型 Lambda 的常见模板语法 | |
__cpp_guaranteed_copy_elision
|
201606
|
[P0135R1] 通过简化值类别保证复制省略的措辞 |
__cpp_hex_float
|
201603
|
[P0245R1] C++ 十六进制浮点字面量 |
__cpp_if_consteval
|
202106
|
[P1938R3] if consteval |
__cpp_if_constexpr
|
201606
|
[P0292R2] constexpr if:一种略有不同的语法 |
__cpp_impl_coroutine
|
201902
|
[P0912R5] 将 Coroutines TS 合并到 C++20 工作草案中 [LWG3393] 协程的缺失/不正确功能测试宏 |
__cpp_impl_destroying_delete
|
201806
|
[P0722R3] 可变大小类的有效大小删除 |
__cpp_impl_three_way_comparison
|
201711
|
[P0515R3] 一致性比较 [P0768R1] 飞船(比较)运算符的库支持 |
201902
|
[P1185R2] <=> != == |
|
201907
|
[P1630R1] 飞船需要调整 | |
__cpp_implicit_move
|
202207
|
[P2266R3] 更简单的隐式移动 |
__cpp_inheriting_constructors
|
200802
|
[N2540] 继承构造函数(修订版 5) |
201511
|
[P0136R1] 重写继承构造函数(核心问题 1941 等) | |
__cpp_init_captures
|
201304
|
[N3648] 广义 Lambda 捕获的措辞更改 |
201803
|
[P0780R2] 允许在 lambda init-capture 中进行包展开 | |
__cpp_initializer_lists
|
200806
|
[N2672] 初始化列表建议措辞 |
__cpp_inline_variables
|
201606
|
[P0386R2] 内联变量 |
__cpp_lambdas
|
200907
|
[N2927] C++0x Lambdas 的新措辞(修订版 2) |
__cpp_modules
|
201907
|
[P1103R3] 合并模块 [P1811R0] 放宽重新定义限制以提高再导出健壮性 |
__cpp_multidimensional_subscript
|
202110
|
[P2128R6] 多维下标运算符 |
202211
|
[P2589R1] 静态 operator[] | |
__cpp_named_character_escapes
|
202207
|
[P2071R2] 命名通用字符转义 |
__cpp_namespace_attributes
|
201411
|
[N4266] 命名空间和枚举器属性 |
__cpp_noexcept_function_type
|
201510
|
[P0012R1] 使异常规范成为类型系统的一部分,版本 5 |
__cpp_nontype_template_args
|
201411
|
[N4268] 允许所有非类型模板参数的常量求值 |
201911
|
[P1907R1] 非类型模板参数的不一致性 | |
__cpp_nontype_template_parameter_auto
|
201606
|
[P0127R2] 使用 auto 声明非类型模板参数 |
__cpp_nontype_template_parameter_class
|
201806
|
[P0732R2] 非类型模板参数中的类类型 |
|
[P1907R1] 非类型模板参数的不一致性 | |
__cpp_nsdmi
|
200809
|
[N2756] 非静态数据成员初始化器 |
__cpp_pack_indexing
|
202311
|
[P2662R3] 包索引 |
__cpp_placeholder_variables
|
202306
|
[P2169R4] 一个没有名字的好占位符 |
__cpp_range_based_for
|
200907
|
[N2930] 基于范围的 for 循环措辞(不含 Concepts) |
201603
|
[P0184R0] 泛化基于范围的 For 循环 | |
202211
|
[P2644R1] 修复损坏的基于范围的 for 循环修订版 1 [P2718R0] P2644R1 修复基于范围的 for 循环的措辞 [CWG2659] range-for 循环中生命周期延长的功能测试宏缺失 |
|
__cpp_raw_strings
|
200710
|
[N2442] 原始字符串和 Unicode 字符串字面量;统一提案(修订版 2) |
__cpp_ref_qualifiers
|
200710
|
[N2439] 将移动语义扩展到 *this (修订措辞) |
__cpp_return_type_deduction
|
201304
|
[N3638] 普通函数的返回类型推断 |
__cpp_rtti
|
199711
|
运行时类型识别 |
__cpp_rvalue_references
|
200610
|
[N2118] 在 C++ 语言中添加右值引用的提案:建议措辞:修订版 3 |
__cpp_size_t_suffix
|
202011
|
[P0330R8] (signed) size_t 的字面量后缀 |
__cpp_sized_deallocation
|
201309
|
[N3778] C++ 大小化解除分配 |
__cpp_static_assert
|
200410
|
[N1720] 将静态断言添加到核心语言的提案(修订版 3) |
201411
|
[N3928] 扩展 static_assert,v2 | |
202306
|
[P2741R3] 用户生成的 static_assert 消息 | |
__cpp_static_call_operator
|
202207
|
[P1169R4] 静态 operator() |
__cpp_structured_bindings
|
201606
|
[P0217R3] 结构化绑定建议措辞 |
202403
|
[P0609R3] 结构化绑定的属性 | |
202411
|
[P1061R10] 结构化绑定可以引入一个包 | |
__cpp_template_parameters
|
202502
|
[P2841R7] 概念和变量模板模板参数 |
__cpp_template_template_args
|
201611
|
[P0522R0] DR:模板模板参数的匹配排除兼容模板 |
__cpp_threadsafe_static_init
|
200806
|
[N2660] 动态初始化和并发销毁 |
__cpp_trivial_relocatability
|
202502
|
[P2786R13] C++26 的微不足道的重新定位能力 |
__cpp_trivial_union
|
202502
|
[P3074R7] 微不足道的 union (曾是 std::uninitialized<T> ) |
__cpp_unicode_characters
|
200704
|
[N2249] C++ 中的新字符类型 |
__cpp_unicode_literals
|
200710
|
[N2442] 原始字符串和 Unicode 字符串字面量;统一提案(修订版 2) |
__cpp_user_defined_literals
|
200809
|
[N2765] 用户定义字面量(又名可扩展字面量(修订版 5)) |
__cpp_using_enum
|
201907
|
[P1099R5] 使用枚举 |
__cpp_variable_templates
|
201304
|
[N3651] 变量模板(修订版 1) |
__cpp_variadic_friend
|
202403
|
[P2893R3] 可变参数友元 |
__cpp_variadic_templates
|
200704
|
[N2242] 可变参数模板建议措辞(修订版 2) |
__cpp_variadic_using
|
201611
|
[P0195R2] using-declaration 中的包扩展 |
4.2 属性功能测试宏
以下所有宏都是预定义的。
宏 | 值 | 论文 |
---|---|---|
__has_cpp_attribute(assume)
|
202207
|
[P1774R8] 可移植假设 [CWG2615] 缺失 __has_cpp_attribute(assume) |
__has_cpp_attribute(carries_dependency)
|
200809
|
[N2782] C++ 数据依赖顺序:函数标注 |
__has_cpp_attribute(deprecated)
|
201309
|
[N3760] [[deprecated]] 属性 |
__has_cpp_attribute(fallthrough)
|
201603
|
[P0188R1] [[fallthrough]] 属性的措辞 |
__has_cpp_attribute(likely)
|
201803
|
[P0479R5] likely 和 unlikely 属性的建议措辞 |
__has_cpp_attribute(maybe_unused)
|
201603
|
[P0212R1] [[maybe_unused]] 属性的措辞 |
__has_cpp_attribute(no_unique_address)
|
201803
|
[P0840R2] 空对象的语言支持 |
__has_cpp_attribute(nodiscard)
|
201603
|
[P0189R1] [[nodiscard]] 属性的措辞 |
201907
|
[P1301R4] [[nodiscard("should have a reason")]] [P1771R1] 构造函数用 [[nodiscard]] |
|
__has_cpp_attribute(noreturn)
|
200809
|
[N2761] C++ 中属性支持的进展(修订版 6) |
__has_cpp_attribute(unlikely)
|
201803
|
[P0479R5] likely 和 unlikely 属性的建议措辞 |
4.3 库功能测试宏
以下所有宏在包含头文件 <version>
或下面指定的相应头文件后定义。
宏 | 头文件 | 值 | 论文 |
---|---|---|---|
__cpp_lib_adaptor_iterator_pair_constructor
|
<queue> <stack> |
202106
|
[P1425R4] 栈和队列的迭代器对构造函数 |
__cpp_lib_addressof_constexpr
|
<memory>
|
201603
|
[LWG2296] std::addressof 应该是 constexpr |
__cpp_lib_algorithm_iterator_requirements
|
<algorithm> <memory> <numeric> |
202207
|
[P2408R5] 将范围迭代器作为非范围算法的输入 |
__cpp_lib_aligned_accessor
|
<mdspan>
|
202411
|
[P2897R7] aligned_accessor:表达指针过对齐的 mdspan 访问器 |
__cpp_lib_allocate_at_least
|
<memory>
|
202106
|
[P0401R6] 在分配器接口中提供大小反馈 |
202306
|
[LWG3887] allocate_at_least 的版本宏 | ||
__cpp_lib_allocator_traits_is_always_equal
|
<deque> <forward_list> <list> <map> <memory> <scoped_allocator> <set> <string> <unordered_map> <unordered_set> <vector> |
201411
|
[N4258] 清理库中的 noexcept (修订版 3) |
__cpp_lib_any
|
<any>
|
201603
|
[P0220R1] 采用库基础 V1 TS 组件用于 C++17 (R1) |
201606
|
[P0032R3] variant、any 和 optional 的同质接口(修订版 3) | ||
__cpp_lib_apply
|
<tuple>
|
201603
|
[P0220R1] 采用库基础 V1 TS 组件用于 C++17 (R1) |
__cpp_lib_array_constexpr
|
<array> <iterator> |
201603
|
[P0031R0] 一个在 reverse_iterator, move_iterator, array 和 Range Access 中添加 Constexpr 修饰符的提案 |
201803
|
[P0858R0] Constexpr 迭代器要求 [LWG3257] P0858 缺少功能测试宏更新 |
||
201806
|
[P1023R0] std::array 的 constexpr 比较运算符 | ||
201811
|
[P1032R1] 杂项 constexpr 位 | ||
__cpp_lib_as_const
|
<utility>
|
201510
|
[P0007R1] 常量视图:std::as_const 辅助函数模板的提案 |
__cpp_lib_associative_heterogeneous_erasure
|
<map> <set> <unordered_map> <unordered_set> |
202110
|
[P2077R3] 关联容器的异构擦除重载 |
__cpp_lib_associative_heterogeneous_insertion
|
<map> <set> <unordered_map> <unordered_set> |
202306
|
[P2363R5] 扩展关联容器以支持其余异构重载 |
__cpp_lib_assume_aligned
|
<memory>
|
201811
|
[P1007R3] std::assume_aligned |
__cpp_lib_atomic_flag_test
|
<atomic>
|
201907
|
[P1135R6] C++20 同步库 |
__cpp_lib_atomic_float
|
<atomic>
|
201711
|
[P0020R6] 浮点原子 |
__cpp_lib_atomic_is_always_lock_free
|
<atomic>
|
201603
|
[P0152R1] constexpr atomic<T>::is_always_lock_free |
__cpp_lib_atomic_lock_free_type_aliases
|
<atomic>
|
201907
|
[P1135R6] C++20 同步库 |
__cpp_lib_atomic_min_max
|
<atomic>
|
202403
|
[P0493R5] 原子最大/最小值 |
__cpp_lib_atomic_ref
|
<atomic>
|
201806
|
[P0019R8] 原子引用 |
202411
|
[P2835R7] 暴露 std::atomic_ref 的对象地址 | ||
<memory>
|
201711
|
[P0718R2] 为 C++20 修订 atomic_shared_ptr | |
__cpp_lib_atomic_value_initialization
|
<atomic> <memory> |
201911
|
[P0883R2] 修复原子初始化 |
__cpp_lib_atomic_wait
|
<atomic>
|
201907
|
[P1135R6] C++20 同步库 |
__cpp_lib_barrier
|
<barrier>
|
201907
|
[P1135R6] C++20 同步库 |
202302
|
[P2588R3] 放宽 std::barrier 阶段完成步骤保证 | ||
__cpp_lib_bind_back
|
<functional>
|
202202
|
[P2387R3] 用户定义范围适配器的管道支持 |
202306
|
[P2714R1] 将前向和后向绑定到 NTTP 可调用对象 | ||
__cpp_lib_bind_front
|
<functional>
|
201811
|
[P0356R5] 简化部分函数应用 |
201907
|
[P1651R0] bind_front 不应解包 reference_wrapper | ||
202306
|
[P2714R1] 将前向和后向绑定到 NTTP 可调用对象 | ||
__cpp_lib_bit_cast
|
<bit>
|
201806
|
[P0476R2] 位转换对象表示 |
__cpp_lib_bitops
|
<bit>
|
201907
|
[P0553R4] 位操作 |
__cpp_lib_bitset
|
<bitset>
|
202306
|
[P2697R1] bitset 与 string_view 的接口 |
__cpp_lib_bool_constant
|
<type_traits>
|
201505
|
[N4389] bool_constant 的措辞,修订版 1 |
__cpp_lib_bounded_array_traits
|
<type_traits>
|
201902
|
[P1357R1] [有界]数组的特性 |
__cpp_lib_boyer_moore_searcher
|
<functional>
|
201603
|
[P0220R1] 采用库基础 V1 TS 组件用于 C++17 (R1) |
__cpp_lib_byte
|
<cstddef>
|
201603
|
[P0298R3] 字节类型定义 |
__cpp_lib_byteswap
|
<bit>
|
202110
|
[P1272R4] Byteswapping for fun&&nuf |
__cpp_lib_char8_t
|
<atomic> <filesystem> <istream> <limits> <locale> <ostream> <string> <string_view> |
201811
|
[P0482R6] char8_t :用于 UTF-8 字符和字符串的类型(修订版 6) |
201907
|
[P1423R3] char8_t 向后兼容性补救 |
||
__cpp_lib_chrono
|
<chrono>
|
201510
|
[P0092R1] 改进 <chrono> |
201611
|
[P0505R0] GB 50 的措辞 | ||
201803
|
[P0355R7] 将 <chrono> 扩展到日历和时区 |
||
201907
|
[P1466R3] chrono 的杂项小修复 | ||
202306
|
[P2592R3] std::chrono 值类的哈希支持 | ||
__cpp_lib_chrono_udls
|
<chrono>
|
201304
|
[N3642] 标准库类型的用户定义字面量(第一部分 - 版本 4) |
__cpp_lib_clamp
|
<algorithm>
|
201603
|
[P0025R0] “夹紧”值介于一对边界值之间的算法 |
__cpp_lib_common_reference
|
<type_traits>
|
202302
|
[P2655R3] common_reference_t of reference_wrapper 应该是一个引用类型 |
__cpp_lib_common_reference_wrapper
|
<functional>
|
202302
|
[P2655R3] common_reference_t of reference_wrapper 应该是一个引用类型 |
__cpp_lib_complex_udls
|
<complex>
|
201309
|
[N3779] std::complex 的用户定义字面量 |
__cpp_lib_concepts
|
<compare> <concepts> |
201806
|
[P0898R3] 标准库概念 |
201907
|
[P1754R1] 将概念重命名为 C++20 的 standard_case,趁我们还能 | ||
202002
|
[P1964R2] boolean-testable 的措辞 |
||
202207
|
[P2404R3] equality_comparable_with, totally_ordered_with 和 three_way_comparable_with 的仅移动类型 | ||
__cpp_lib_constexpr_algorithms
|
<algorithm> <utility> |
201703
|
[P0202R3] 为 <algorithm> 和 <utility> 头文件中的函数添加 Constexpr 修饰符 |
201806
|
[P0879R0] 交换及相关函数的 constexpr [LWG3256] constexpr 算法的功能测试宏 [LWG3792] __cpp_lib_constexpr_algorithms 也应该定义在 |
||
202306
|
[P2562R1] constexpr 稳定排序 | ||
__cpp_lib_constexpr_atomic
|
<atomic>
|
202411
|
[P3309R3] constexpr atomic and atomic_ref |
__cpp_lib_constexpr_bitset
|
<bitset>
|
202207
|
[P2417R2] 更强的 constexpr bitset |
__cpp_lib_constexpr_charconv
|
<charconv>
|
202207
|
[P2291R3] 在头文件中为整型类型的 to_chars 和 from_chars 函数添加 Constexpr 修饰符 |
__cpp_lib_constexpr_cmath
|
<cmath> <cstdlib> |
202202
|
[P0533R9] cmath 和 cstdlib 的 constexpr |
202306
|
[P1383R2] cmath 和 complex 的更多 constexpr | ||
__cpp_lib_constexpr_complex
|
<complex>
|
201711
|
[P0415R1] std::complex 的 Constexpr |
202306
|
[P1383R2] cmath 和 complex 的更多 constexpr | ||
__cpp_lib_constexpr_deque
|
<deque>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_dynamic_alloc
|
<memory>
|
201907
|
[P0784R7] 更多 constexpr 容器 |
__cpp_lib_constexpr_exceptions
|
<exception> <expected> <format> <optional> <stdexcept> <variant> |
202411
|
[P3068R6] 允许在常量求值中抛出异常 |
202502
|
[P3378R2] constexpr 异常类型 | ||
__cpp_lib_constexpr_flat_map
|
<flat_map>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_flat_set
|
<flat_set>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_forward_list
|
<forward_list>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_functional
|
<functional>
|
201811
|
[P1032R1] 杂项 constexpr 位 |
201907
|
[P1065R2] constexpr INVOKE |
||
__cpp_lib_constexpr_inplace_vector
|
<inplace_vector>
|
202502
|
[P3542R0] 废除“转换构造函数”一词 |
__cpp_lib_constexpr_iterator
|
<iterator>
|
201811
|
[P1032R1] 杂项 constexpr 位 |
__cpp_lib_constexpr_list
|
<list>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_map
|
<map>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_memory
|
<memory>
|
201811
|
[P1006R1] std::pointer_traits 中的 Constexpr |
202202
|
[P2273R3] 使 std::unique_ptr constexpr 化 | ||
__cpp_lib_constexpr_new
|
<new>
|
202406
|
[P2747R2] constexpr placement new |
__cpp_lib_constexpr_numeric
|
<numeric>
|
201911
|
[P1645R1] 数值算法的 constexpr |
__cpp_lib_constexpr_queue
|
<queue>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_set
|
<set>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_stack
|
<stack>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_string
|
<string>
|
201611
|
[P0426R1] std::char_traits 的 Constexpr |
201811
|
[P1032R1] 杂项 constexpr 位 | ||
201907
|
[P0980R1] 使 std::string constexpr 化 |
||
__cpp_lib_constexpr_string_view
|
<string_view>
|
201611
|
[P0426R1] std::char_traits 的 Constexpr |
201811
|
[P1032R1] 杂项 constexpr 位 | ||
__cpp_lib_constexpr_tuple
|
<tuple>
|
201811
|
[P1032R1] 杂项 constexpr 位 |
__cpp_lib_constexpr_typeinfo
|
<typeinfo>
|
202106
|
[P1328R1] 使 std::type_info::operator== constexpr |
__cpp_lib_constexpr_unordered_map
|
<unordered_map>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_unordered_set
|
<unordered_set>
|
202502
|
[P3372R3] constexpr 容器和适配器 |
__cpp_lib_constexpr_utility
|
<utility>
|
201811
|
[P1032R1] 杂项 constexpr 位 |
__cpp_lib_constexpr_vector
|
<vector>
|
201907
|
[P1004R2] 使 std::vector constexpr 化 |
__cpp_lib_constrained_equality
|
<optional> <tuple> <utility> <variant> |
202403
|
[P2944R3] reference_wrapper 的比较 |
202411
|
[P3379R0] 约束 std::expected 相等运算符 | ||
__cpp_lib_containers_ranges
|
<deque> <forward_list> <list> <map> <queue> <set> <stack> <string> <unordered_map> <unordered_set> <vector> |
202202
|
[P1206R7] 从 Ranges 到容器的转换 |
__cpp_lib_contracts
|
<contracts>
|
202502
|
[P2900R14] C++ 契约 |
__cpp_lib_copyable_function
|
<functional>
|
202306
|
[P2548R6] copyable_function |
__cpp_lib_coroutine
|
<coroutine>
|
201902
|
[P0912R5] 将 Coroutines TS 合并到 C++20 工作草案中 [LWG3393] 协程的缺失/不正确功能测试宏 |
__cpp_lib_debugging
|
<debugging>
|
202311
|
[P2546R5] 调试支持 |
202403
|
[P2810R4] is_debugger_present 可替换 | ||
__cpp_lib_deduction_guides
|
201703
|
[P0433R2] 解决 US7 和 US14:将类模板的模板推导集成到标准库中 | |
__cpp_lib_default_template_type_for_algorithm_values
|
<algorithm> <deque> <forward_list> <list> <ranges> <string> <vector> |
202403
|
[P2248R8] 为算法启用列表初始化 |
__cpp_lib_destroying_delete
|
<new>
|
201806
|
[P0722R3] 可变大小类的有效大小删除 |
<memory>
|
201603
|
[P0033R1] 重新启用 shared_from_this (修订版 1) | |
__cpp_lib_endian
|
<bit>
|
201907
|
[P0463R1] endian,仅 endian [P1612R1] 重新定位 Endian 的规范 |
__cpp_lib_erase_if
|
<deque> <forward_list> <list> <map> <set> <string> <unordered_map> <unordered_set> <vector> |
201811
|
[P1209R0] 采用 Library Fundamentals 2 中的一致容器擦除功能用于 C++20 |
202002
|
[P1115R3] 改进擦除类算法的返回值 II:自由擦除/条件擦除 | ||
__cpp_lib_exchange_function
|
<utility>
|
201304
|
[N3668] exchange() 实用函数,修订版 3 |
__cpp_lib_execution
|
<execution>
|
201603
|
[P0024R2] 并行化 TS 应该标准化 |
201902
|
[P1001R2] 将并行化 V2 TS 中的目标向量化策略应用于 C++20 | ||
__cpp_lib_expected
|
<expected>
|
202202
|
[P0323R12] std::expected |
202211
|
[P2505R5] std::expected 的 Monadic 函数 | ||
__cpp_lib_filesystem
|
<filesystem>
|
201603
|
[P0218R1] 采用 C++17 的文件系统 TS |
201606
|
[P0219R1] 文件系统的相对路径 [P0392R0] 适应文件系统路径的 string_view |
||
201703
|
[P0317R1] 文件系统的目录项缓存 | ||
__cpp_lib_flat_map
|
<flat_map>
|
202207
|
[P0429R9] 一个标准 flat_map |
__cpp_lib_flat_set
|
<flat_set>
|
202207
|
[P1222R4] 一个标准 flat_set [LWG3751] flat_set 缺少特性宏 |
__cpp_lib_format
|
<format>
|
201907
|
[P0645R10] 文本格式化 [P1361R2] chrono 与文本格式化的集成 [P1652R1] std::format 中的 Printf 角落案例 |
202106
|
[P2216R3] std::format 改进 | ||
202110
|
[P2372R3] 修复 chrono 格式化程序中的区域设置处理 [P2418R2] 为 std::format 添加对 std::generator 类似类型的支持 |
||
202207
|
[P2419R2] 澄清 chrono 类型本地化格式化中编码的处理 [P2508R1] 暴露 std::basic-format-string |
||
202304
|
[P2510R3] 格式化指针 | ||
202305
|
[P2757R3] 类型检查格式参数 | ||
202306
|
[P2637R3] 成员访问 | ||
202311
|
[P2918R2] 运行时格式字符串 II | ||
__cpp_lib_format_path
|
<filesystem>
|
202403
|
[P2845R8] std::filesystem::path 的格式化 |
__cpp_lib_format_ranges
|
<format>
|
202207
|
[P2286R8] 格式化 Ranges [P2585R1] 改进默认容器格式化 [LWG3750] 太多论文更新了 __cpp_lib_format |
__cpp_lib_format_uchar
|
<format>
|
202311
|
[P2909R4] 修复代码单元作为整数的格式化(Dude,我的 char 在哪?) |
__cpp_lib_forward_like
|
<utility>
|
202207
|
[P2445R1] forward_like |
__cpp_lib_freestanding_algorithm
|
<algorithm>
|
202311
|
[P2407R5] 独立库:部分类 |
202502
|
[P2976R1] 独立库:algorithm、numeric 和 random | ||
__cpp_lib_freestanding_array
|
<array>
|
202311
|
[P2407R5] 独立库:部分类 |
__cpp_lib_freestanding_char_traits
|
<string>
|
202306
|
[P2338R4] 独立库:字符原语和 C 库 |
__cpp_lib_freestanding_charconv
|
<charconv>
|
202306
|
[P2338R4] 独立库:字符原语和 C 库 |
__cpp_lib_freestanding_cstdlib
|
<cmath> <cstdlib> |
202306
|
[P2338R4] 独立库:字符原语和 C 库 |
__cpp_lib_freestanding_cstring
|
<cstring>
|
202306
|
[P2338R4] 独立库:字符原语和 C 库 |
202311
|
[P2937R0] 独立:移除 strtok | ||
__cpp_lib_freestanding_cwchar
|
<cwchar>
|
202306
|
[P2338R4] 独立库:字符原语和 C 库 |
__cpp_lib_freestanding_errc
|
<cerrno> <system_error> |
202306
|
[P2338R4] 独立库:字符原语和 C 库 |
__cpp_lib_freestanding_execution
|
<execution>
|
202502
|
[P2976R1] 独立库:algorithm、numeric 和 random |
__cpp_lib_freestanding_expected
|
<expected>
|
202311
|
[P2833R2] 独立库:inout expected span |
__cpp_lib_freestanding_feature_test_macros
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 | |
__cpp_lib_freestanding_functional
|
<functional>
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 |
__cpp_lib_freestanding_iterator
|
<iterator>
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 |
__cpp_lib_freestanding_mdspan
|
<mdspan>
|
202311
|
[P2833R2] 独立库:inout expected span |
__cpp_lib_freestanding_memory
|
<memory>
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 |
202502
|
[P2976R1] 独立库:algorithm、numeric 和 random | ||
__cpp_lib_freestanding_numeric
|
<numeric>
|
202502
|
[P2976R1] 独立库:algorithm、numeric 和 random |
__cpp_lib_freestanding_operator_new
|
<operator_new>
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 |
__cpp_lib_freestanding_optional
|
<optional>
|
202311
|
[P2407R5] 独立库:部分类 |
__cpp_lib_freestanding_random
|
<random>
|
202502
|
[P2976R1] 独立库:algorithm、numeric 和 random |
__cpp_lib_freestanding_ranges
|
<ranges>
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 |
__cpp_lib_freestanding_ratio
|
<ratio>
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 |
__cpp_lib_freestanding_string_view
|
<string_view>
|
202311
|
[P2407R5] 独立库:部分类 |
__cpp_lib_freestanding_tuple
|
<tuple>
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 |
__cpp_lib_freestanding_utility
|
<utility>
|
202306
|
[P2198R7] 独立特性测试宏和实现定义扩展 |
__cpp_lib_freestanding_variant
|
<variant>
|
202311
|
[P2407R5] 独立库:部分类 |
__cpp_lib_fstream_native_handle
|
<fstream>
|
202306
|
[P1759R6] 本机句柄和文件流 |
__cpp_lib_function_ref
|
<functional>
|
202306
|
[P0792R14] function_ref: 一个非拥有可调用对象引用 |
__cpp_lib_gcd_lcm
|
<numeric>
|
201606
|
[P0295R0] 采用 C++17 的 Library Fundamentals V2 精选组件 |
__cpp_lib_generate_random
|
<random>
|
202403
|
[P1068R11] 随机数生成的向量 API |
__cpp_lib_generator
|
<generator>
|
202207
|
[P2502R2] std::generator: Ranges 的同步协程生成器 |
__cpp_lib_generic_associative_lookup
|
<map> <set> |
201304
|
[N3657] 为关联容器添加异构比较查找(修订版 4) |
__cpp_lib_generic_unordered_hash_lookup
|
<unordered_map> <unordered_set> |
201902
|
[P0920R2] 查找中的预计算哈希值 |
|
[P1661R1] 移除专用预计算哈希查找接口 | ||
__cpp_lib_generic_unordered_lookup
|
<unordered_map> <unordered_set> |
201811
|
[P0919R3] 无序容器的异构查找 |
__cpp_lib_hardened_array
|
<array>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_basic_string
|
<string>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_basic_string_view
|
<string_view>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_bitset
|
<bitset>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_deque
|
<deque>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_expected
|
<expected>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_forward_list
|
<forward_list>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_inplace_vector
|
<inplace_vector>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_list
|
<list>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_mdspan
|
<mdspan>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_optional
|
<optional>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_span
|
<span>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_valarray
|
<valarray>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardened_vector
|
<vector>
|
202502
|
[P3471R4] 标准库强化 |
__cpp_lib_hardware_interference_size
|
<new>
|
201703
|
[P0154R1] constexpr std::thread::hardware_{true,false}_sharing_size |
__cpp_lib_has_unique_object_representations
|
<type_traits>
|
201606
|
[P0258R2] has_unique_object_representations - 措辞 |
__cpp_lib_hazard_pointer
|
<hazard_pointer>
|
202306
|
[P2545R4] 读-复制-更新 (RCU) |
__cpp_lib_hive
|
<hive>
|
202502
|
[P0447R28] 将 std::hive 引入标准库 |
__cpp_lib_hypot
|
<cmath>
|
201603
|
[P0030R1] 提议向 std::hypot 引入一个 3 参数重载 |
__cpp_lib_incomplete_container_elements
|
<forward_list> <list> <vector> |
201505
|
[N4510] 标准容器的最小不完整类型支持,修订版 4 |
__cpp_lib_indirect
|
<memory>
|
202502
|
[P3019R11] 复合类设计的词汇类型 |
__cpp_lib_inplace_vector
|
<inplace_vector>
|
202406
|
[P0843R14] inplace_vector |
__cpp_lib_int_pow2
|
<bit>
|
201806
|
[P0556R3] 整数 2 的幂运算 |
202002
|
[P1956R1] 关于低级位操作函数的命名 | ||
__cpp_lib_integer_comparison_functions
|
<utility>
|
202002
|
[P0586R2] 安全的整数比较 |
__cpp_lib_integer_sequence
|
<utility>
|
201304
|
[N3658] 编译时整数序列 |
__cpp_lib_integral_constant_callable
|
<type_traits>
|
201304
|
[N3545] integral_constant 的渐进改进 |
__cpp_lib_interpolate
|
<cmath> <numeric> |
201902
|
[P0811R3] 数字和指针的良好插值 |
__cpp_lib_invoke
|
<functional>
|
201411
|
[N4169] 提议添加 invoke 函数模板(修订版 1) |
__cpp_lib_invoke_r
|
<functional>
|
202106
|
[P2136R3] invoke_r |
__cpp_lib_ios_noreplace
|
<ios>
|
202207
|
[P2467R1] 支持 fstream 的独占模式 |
__cpp_lib_is_aggregate
|
<type_traits>
|
201703
|
[LWG2911] 需要 is_aggregate 类型特性 |
__cpp_lib_is_constant_evaluated
|
<type_traits>
|
201811
|
[P0595R2] std::is_constant_evaluated |
__cpp_lib_is_final
|
<type_traits>
|
201402
|
[LWG2112] 无法派生的用户定义类 |
__cpp_lib_is_implicit_lifetime
|
<type_traits>
|
202302
|
[P2674R1] 隐式生命周期类型的特性 |
__cpp_lib_is_invocable
|
<type_traits>
|
201703
|
[P0604R0] 解决 GB 55, US 84, US 85, US 86 |
__cpp_lib_is_layout_compatible
|
<type_traits>
|
201907
|
[P0466R5] 布局兼容性和指针可互转换性特性 |
__cpp_lib_is_nothrow_convertible
|
<type_traits>
|
201806
|
[P0758R1] 隐式转换特性和实用函数 [LWG3356] __cpp_lib_nothrow_convertible 应该改为 __cpp_lib_is_nothrow_convertible |
__cpp_lib_is_null_pointer
|
<type_traits>
|
201309
|
[LWG2247] 类型特性和 std::nullptr_t |
__cpp_lib_is_pointer_interconvertible
|
<type_traits>
|
201907
|
[P0466R5] 布局兼容性和指针可互转换性特性 |
__cpp_lib_is_scoped_enum
|
<type_traits>
|
202011
|
[P1048R1] 用于检测范围枚举的类型特性提议 |
__cpp_lib_is_sufficiently_aligned
|
<memory>
|
202411
|
[P2897R7] aligned_accessor:表达指针过对齐的 mdspan 访问器 |
__cpp_lib_is_swappable
|
<type_traits>
|
201603
|
[P0185R1] 添加 [nothrow-]swappable 特性,修订版 3 |
__cpp_lib_is_virtual_base_of
|
<type_traits>
|
202406
|
[P2985R0] 用于检测虚基类的类型特性 |
__cpp_lib_is_within_lifetime
|
<type_traits>
|
202306
|
[P2641R4] 检查联合体候选项是否激活 |
__cpp_lib_jthread
|
<stop_token> <thread> |
201907
|
[P0660R10] Stop Token 和 Joining Thread |
201911
|
[P1869R1] 重命名 ‘condition_variable_any’ 可中断等待方法 | ||
__cpp_lib_latch
|
<latch>
|
201907
|
[P1135R6] C++20 同步库 |
__cpp_lib_launder
|
<new>
|
201606
|
[P0137R1] 核心问题 1776:包含引用成员的类对象的替换 |
__cpp_lib_linalg
|
<linalg>
|
202311
|
[P1673R13] 基于 BLAS 的自由函数线性代数接口 |
202411
|
[P3050R2] 通过优化 linalg::conjugated 用于非复数值类型来修复 C++26 [P3222R0] 通过为 P2642 布局添加转置特殊情况来修复 C++26 |
||
__cpp_lib_list_remove_return_type
|
<forward_list> <list> |
201806
|
[P0646R1] 改进擦除类算法的返回值 I:list/forward list |
__cpp_lib_logical_traits
|
<type_traits>
|
201510
|
[P0013R1] 逻辑运算符类型特性(修订版 1) |
__cpp_lib_make_from_tuple
|
<tuple>
|
201606
|
[P0209R2] make_from_tuple: 构造时的应用 |
__cpp_lib_make_reverse_iterator
|
<iterator>
|
201402
|
[LWG2285] make_reverse_iterator |
__cpp_lib_make_unique
|
<memory>
|
201304
|
[N3656] make_unique(修订版 1) |
__cpp_lib_map_try_emplace
|
<map>
|
201411
|
[N4279] 唯一键映射的改进插入接口(修订版 2.3) |
__cpp_lib_math_constants
|
<numbers>
|
201907
|
[P0631R8] 数学常数 |
__cpp_lib_math_special_functions
|
<cmath>
|
201603
|
[P0226R1] C++17 的数学特殊函数,v5 |
__cpp_lib_mdspan
|
<mdspan>
|
202207
|
[P0009R18] MDSPAN [P2599R2] mdspan 中的 index _type & size_type [P2604R0] MDSPAN:重命名 pointer 和 contiguous [P2613R1] 为 mdspan 添加缺失的 empty |
202406
|
[P2389R2] dextents 索引类型参数 | ||
__cpp_lib_memory_resource
|
<memory_resource>
|
201603
|
[P0220R1] 采用库基础 V1 TS 组件用于 C++17 (R1) |
__cpp_lib_modules
|
202207
|
[P2465R3] 标准库模块 std 和 std.compat | |
__cpp_lib_monadic_optional
|
<optional>
|
202110
|
[P0798R8] std::optional 的 Monadic 操作 |
|
[LWG3621] 移除特性测试宏 __cpp_lib_monadic_optional | ||
__cpp_lib_move_iterator_concept
|
<iterator>
|
202207
|
[P2520R0] move_iterator 应该是随机访问迭代器 |
__cpp_lib_move_only_function
|
<functional>
|
202110
|
[P0288R9] move_only_function(原 any_invocable) |
__cpp_lib_node_extract
|
<map> <set> <unordered_map> <unordered_set> |
201606
|
[P0083R3] 拼接映射和集合(修订版 5) |
__cpp_lib_nonmember_container_access
|
<array> <deque> <forward_list> <iterator> <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector> |
201411
|
[N4280] 非成员 size() 和更多(修订版 2) |
__cpp_lib_not_fn
|
<functional>
|
201603
|
[P0005R4] 采用 Library Fundamentals 2 中的 not_fn 用于 C++17 |
202306
|
[P2714R1] 将前向和后向绑定到 NTTP 可调用对象 | ||
__cpp_lib_null_iterators
|
<iterator>
|
201304
|
[N3644] 空前向迭代器 |
__cpp_lib_optional
|
<optional>
|
201603
|
[P0220R1] 采用库基础 V1 TS 组件用于 C++17 (R1) |
201606
|
[P0032R3] variant、any 和 optional 的同质接口(修订版 3) [P0307R2] 使 Optional 再次相等 |
||
202106
|
[P2231R1] 为 optional/variant 添加更多 constexpr 支持 | ||
202110
|
[P0798R8] std::optional 的 Monadic 操作 [LWG3621] 移除特性测试宏 __cpp_lib_monadic_optional |
||
__cpp_lib_optional_range_support
|
<optional>
|
202406
|
[P3168R2] 为 std::optional 提供 Range 支持 |
__cpp_lib_out_ptr
|
<memory>
|
202106
|
[P1132R7] out_ptr - 可伸缩的输出指针抽象 |
202311
|
[P2833R2] 独立库:inout expected span | ||
__cpp_lib_parallel_algorithm
|
<algorithm> <numeric> |
201603
|
[P0024R2] 并行化 TS 应该标准化 |
__cpp_lib_philox_engine
|
<random>
|
202406
|
[P2075R6] Philox 作为 C++ RNG 引擎的扩展 |
__cpp_lib_polymorphic
|
<memory>
|
202502
|
[P3019R11] 复合类设计的词汇类型 |
__cpp_lib_polymorphic_allocator
|
<memory_resource>
|
201902
|
[P0339R6] polymorphic_allocator<> 作为词汇类型 [LWG3437] __cpp_lib_polymorphic_allocator 位于错误的头文件中 |
__cpp_lib_print
|
<ostream> <print> |
202207
|
[P2093R14] 格式化输出 |
202403
|
[P3107R5] 允许高效实现 std::print | ||
202406
|
[P3235R3] std::print 用更少的内存更快地打印更多类型 | ||
__cpp_lib_quoted_string_io
|
<iomanip>
|
201304
|
[N3654] 引号字符串库提案(修订版 2) |
__cpp_lib_ranges
|
<algorithm> <functional> <iterator> <memory> <ranges> |
201811
|
[P0896R4] 统一 Ranges 提案 |
201907
|
[P1035R7] 输入范围适配器 | ||
201911
|
[P1716R3] ranges 比较算法约束过严 | ||
202106
|
[P2325R3] 视图不应要求默认可构造 | ||
202110
|
[P2415R2] 什么是视图? | ||
202202
|
[P2387R3] 用户定义范围适配器的管道支持 | ||
202207
|
[P2494R2] 放宽范围适配器以允许仅移动类型 | ||
202211
|
[P2602R2] 毒丸太毒了 | ||
202302
|
[P2609R3] 稍稍放宽 Ranges | ||
202406
|
[P2997R1] 移除间接可调用概念中的公共引用要求 | ||
__cpp_lib_ranges_as_const
|
<ranges>
|
202207
|
[P2278R4] cbegin 应该总是返回一个常量迭代器 |
202311
|
[P2836R1] std::basic_const_iterator 应该遵循其底层类型的可转换性 | ||
__cpp_lib_ranges_as_rvalue
|
<ranges>
|
202207
|
[P2446R2] views::as_rvalue |
__cpp_lib_ranges_cache_latest
|
<ranges>
|
202411
|
[P3138R5] views::cache_latest |
__cpp_lib_ranges_cartesian_product
|
<ranges>
|
202207
|
[P2374R4] views::cartesian_product [P2540R1] 某些视图的空积 |
__cpp_lib_ranges_chunk
|
<ranges>
|
202202
|
[P2442R1] 窗口范围适配器:views::chunk 和 views::slide |
__cpp_lib_ranges_chunk_by
|
<ranges>
|
202202
|
[P2443R1] views::chunk_by |
__cpp_lib_ranges_concat
|
<ranges>
|
202403
|
[P2542R8] views::concat |
__cpp_lib_ranges_contains
|
<algorithm>
|
202207
|
[P2302R4] std::ranges::contains |
__cpp_lib_ranges_enumerate
|
<ranges>
|
202302
|
[P2164R9] views::enumerate |
__cpp_lib_ranges_find_last
|
<algorithm>
|
202207
|
[P1223R5] find_last [LWG3807] ranges::find_last 的特性测试宏应重命名 |
__cpp_lib_ranges_fold
|
<algorithm>
|
202207
|
[P2322R6] ranges::fold |
__cpp_lib_ranges_iota
|
<numeric>
|
202202
|
[P2440R1] ranges::iota, ranges::shift_left 和 ranges::shift_right |
__cpp_lib_ranges_join_with
|
<ranges>
|
202202
|
[P2441R2] views::join_with |
__cpp_lib_ranges_repeat
|
<ranges>
|
202207
|
[P2474R2] views::repeat |
__cpp_lib_ranges_reserve_hint
|
<ranges>
|
202502
|
[P2846R6] reserve_hint: 为不完全大小的惰性范围预留内存 |
__cpp_lib_ranges_slide
|
<ranges>
|
202202
|
[P2442R1] 窗口范围适配器:views::chunk 和 views::slide |
__cpp_lib_ranges_starts_ends_with
|
<algorithm>
|
202106
|
[P1659R3] starts_with 和 ends_with |
__cpp_lib_ranges_stride
|
<ranges>
|
202207
|
[P1899R3] stride_view |
__cpp_lib_ranges_to_container
|
<ranges>
|
202202
|
[P1206R7] 从 Ranges 到容器的转换 |
__cpp_lib_ranges_to_input
|
<ranges>
|
202502
|
[P3137R3] views::to_input |
__cpp_lib_ranges_zip
|
<ranges> <tuple> <utility> |
202110
|
[P2321R2] zip |
__cpp_lib_ratio
|
<ratio>
|
202306
|
[P2734R0] 添加新的 2022 SI 前缀 |
__cpp_lib_raw_memory_algorithms
|
<memory>
|
201606
|
[P0040R3] 扩展内存管理工具 |
202411
|
[P3369R0] uninitialized_default_construct 的 constexpr [P3508R0] 专用内存算法的 constexpr 措辞 |
||
__cpp_lib_rcu
|
<rcu>
|
202306
|
[P2545R4] 读-复制-更新 (RCU) |
__cpp_lib_reference_from_temporary
|
<type_traits>
|
202202
|
[P2255R2] 用于检测引用绑定到临时对象的类型特性 |
__cpp_lib_reference_wrapper
|
<functional>
|
202403
|
[P2944R3] reference_wrapper 的比较 |
__cpp_lib_remove_cvref
|
<type_traits>
|
201711
|
[P0550R2] 转换特性 remove_cvref |
__cpp_lib_result_of_sfinae
|
<functional> <type_traits> |
201210
|
[N3462] std::result_of 和 SFINAE |
__cpp_lib_robust_nonmodifying_seq_ops
|
<algorithm>
|
201304
|
[N3671] 使非修改序列操作更健壮:修订版 2 |
__cpp_lib_sample
|
<algorithm>
|
201603
|
[P0220R1] 采用库基础 V1 TS 组件用于 C++17 (R1) |
__cpp_lib_saturation_arithmetic
|
<numeric>
|
202311
|
[P0543R3] 饱和算术 |
__cpp_lib_scoped_lock
|
<mutex>
|
201703
|
[P0156R2] Variadic lock_guard (修订版 4) |
__cpp_lib_semaphore
|
<semaphore>
|
201907
|
[P1135R6] C++20 同步库 |
__cpp_lib_senders
|
<execution>
|
202406
|
[P2300R10] std::execution |
<shared_mutex>
|
201505
|
[N4508] 提议添加 shared_mutex(无定时)(修订版 4) | |
<memory>
|
201611
|
[P0497R0] 修复 shared_ptr 对数组的支持 | |
201707
|
[P0674R1] 扩展 make_shared 以支持数组 | ||
<memory>
|
201606
|
[P0163R0] shared_ptr::weak_type |
|
<shared_mutex>
|
201402
|
[N3891] 提议将 shared_mutex 重命名为 shared_timed_mutex | |
__cpp_lib_shift
|
<algorithm>
|
201806
|
[P0769R2] 将 shift 添加到 <algorithm> |
202202
|
[P2440R1] ranges::iota, ranges::shift_left 和 ranges::shift_right | ||
__cpp_lib_simd
|
<simd>
|
202411
|
[P1928R15] std::simd - 合并并行性 TS 2 中的数据并行类型 |
202502
|
[P2933R4] 扩展 [P3287R3] std::simd 的命名空间探索 [P3441R2] 将 simd_split 重命名为 simd_chunk |
||
__cpp_lib_simd_complex
|
<simd>
|
202502
|
[P2663R7] 支持 std::simd 中交错复杂值的提案 |
__cpp_lib_smart_pointer_owner_equality
|
<memory>
|
202306
|
[P1901R2] 允许在无序关联容器中使用 weak_ptr 作为键 |
__cpp_lib_smart_ptr_for_overwrite
|
<memory>
|
202002
|
[P1020R1] 带有默认初始化的智能指针创建 [P1973R1] 重命名 _default_init 函数(NB 评论 DE002) |
__cpp_lib_source_location
|
<source_location>
|
201907
|
[P1208R6] 采用 Library Fundamentals V3 中的 source location 用于 C++20 |
__cpp_lib_span
|
<span>
|
201803
|
[P0122R7] span:对象的序列的边界安全视图 [LWG3274] 缺少 <span> 的特性测试宏 |
201902
|
[P1024R3] std::span 的可用性增强 |
||
202002
|
[P1976R2] 从动态范围构造固定大小的 span |
||
202311
|
[P2821R5] span.at() [P2833R2] 独立库:inout expected span |
||
__cpp_lib_span_initializer_list
|
<span>
|
202311
|
[P2447R6] initializer list 上的 std::span |
__cpp_lib_spanstream
|
<spanstream>
|
202106
|
[P0448R4] 使用 span 作为缓冲区的 strstream 替换 |
__cpp_lib_ssize
|
<iterator>
|
201902
|
[P1227R2] 有符号 ssize() 函数,无符号 size() 函数 |
__cpp_lib_sstream_from_string_view
|
<sstream>
|
202306
|
[P2495R3] stringstream 与 string_view 的接口 |
__cpp_lib_stacktrace
|
<stacktrace>
|
202011
|
[P0881R7] 提议添加堆栈跟踪库 |
__cpp_lib_start_lifetime_as
|
<memory>
|
202207
|
[P2590R2] 显式生命周期管理 |
__cpp_lib_starts_ends_with
|
<string> <string_view> |
201711
|
[P0457R2] 字符串前缀和后缀检查 |
__cpp_lib_stdatomic_h
|
<stdatomic.h>
|
202011
|
[P0943R6] 支持 C 原子操作在 C++ 中 |
__cpp_lib_string_contains
|
<string> <string_view> |
202011
|
[P1679R3] 字符串包含函数 |
__cpp_lib_string_resize_and_overwrite
|
<string>
|
202110
|
[P1072R10] basic_string::resize_and_overwrite |
__cpp_lib_string_udls
|
<string>
|
201304
|
[N3642] 标准库类型的用户定义字面量(第一部分 - 版本 4) |
__cpp_lib_string_view
|
<string> <string_view> |
201603
|
[P0220R1] 采用库基础 V1 TS 组件用于 C++17 (R1) |
201606
|
[P0254R2] 集成 std::string_view 和 std::string |
||
201803
|
[P0858R0] Constexpr 迭代器要求 [LWG3257] P0858 缺少功能测试宏更新 |
||
202403
|
[P2591R5] 字符串和字符串视图的连接 | ||
__cpp_lib_submdspan
|
<mdspan>
|
202306
|
[P2630R4] Submdspan |
202403
|
[P2642R6] 填充 mdspan 布局 | ||
202411
|
[P3355R1] 修复 C++26 的 submdspan | ||
__cpp_lib_syncbuf
|
<syncstream>
|
201711
|
[P0053R7] C++ 同步缓冲输出流 |
201803
|
[P0753R2] C++ 同步缓冲输出流的操作器 | ||
__cpp_lib_text_encoding
|
<text_encoding>
|
202306
|
[P1885R12] 命名文本编码以消除神秘感 |
__cpp_lib_three_way_comparison
|
<compare>
|
201711
|
[P0768R1] 飞船(比较)运算符的库支持 |
201907
|
[P1614R2] 母舰已着陆:向库中添加 <=> |
||
__cpp_lib_to_address
|
<memory>
|
201711
|
[P0653R2] 将指针转换为原始指针的实用程序 |
__cpp_lib_to_array
|
<array>
|
201907
|
[P0325R4] LFTS 的 to_array 及更新 |
__cpp_lib_to_chars
|
<charconv>
|
201611
|
[P0067R5] 基本字符串转换,修订版 5 [P0682R1] 修复基本字符串转换 [LWG3137] __cpp_lib_to_chars 的头文件 |
202306
|
[P2497R0] charconv 函数的成功或失败测试 | ||
__cpp_lib_to_string
|
<string>
|
202306
|
[P2587R3] to_string 还是 not to_string |
__cpp_lib_to_underlying
|
<utility>
|
202102
|
[P1682R2] std::to_underlying |
__cpp_lib_transformation_trait_aliases
|
<type_traits>
|
201304
|
[N3655] TransformationTraits Redux, v2 |
__cpp_lib_transparent_operators
|
<functional> <memory> |
201210
|
[N3421] 使运算符函数对象 greater<> |
201510
|
[P0074R0] 使 std::owner_less 更灵活 |
||
__cpp_lib_trivially_relocatable
|
<memory> <type_traits> |
202502
|
[P2786R13] C++26 的微不足道的重新定位能力 |
__cpp_lib_tuple_element_t
|
<tuple>
|
201402
|
[N3887] 一致的元函数别名 |
__cpp_lib_tuple_like
|
<map> <tuple> <unordered_map> <utility> |
202207
|
[P2165R4] tuple、pair 和类似 tuple 对象之间的兼容性 |
202311
|
[P2819R2] 为 complex 添加 tuple 协议 | ||
__cpp_lib_tuples_by_type
|
<tuple> <utility> |
201304
|
[N3670] 按类型寻址元组的措辞:修订版 2 |
__cpp_lib_type_identity
|
<type_traits>
|
201806
|
[P0887R1] 恒等元函数 |
__cpp_lib_type_trait_variable_templates
|
<type_traits>
|
201510
|
[P0006R0] 采用 Library Fundamentals TS 中的类型特性变量模板用于 C++17 |
__cpp_lib_uncaught_exceptions
|
<exception>
|
201411
|
[N4259] std::uncaught_exceptions 的措辞 |
__cpp_lib_unordered_map_try_emplace
|
<unordered_map>
|
201411
|
[N4279] 唯一键映射的改进插入接口(修订版 2.3) |
__cpp_lib_unreachable
|
<utility>
|
202202
|
[P0627R6] 标记不可达代码的函数 |
__cpp_lib_unwrap_ref
|
<type_traits>
|
201811
|
[P0318R1] unwrap_ref_decay 和 unwrap_reference [LWG3348] __cpp_lib_unwrap_ref 位于错误的头文件中 |
__cpp_lib_variant
|
<variant>
|
201606
|
[P0088R3] Variant:C++17 的类型安全 union (v8) [P0393R3] 使 Variant 再次相等 [P0032R3] variant、any 和 optional 的同质接口(修订版 3) |
202102
|
[P2162R2] 继承自 std::variant(解决 LWG3052) | ||
202106
|
[P2231R1] 为 optional/variant 添加更多 constexpr 支持 | ||
202306
|
[P2637R3] 成员访问 | ||
__cpp_lib_void_t
|
<type_traits>
|
201411
|
[N3911] TransformationTrait 别名 void_t |