C++ 具名要求-全库范围的概念 -包含分配信息的类类型(Allocator)

此页面中列出的具名要求,是 C++ 标准的规范性文本中使用的具名要求,用于定义标准库的期待。

某些具名要求在 C++20 中正在以概念语言特性进行形式化。在那之前,确保以满足这些要求的模板实参实例化标准库模板是程序员的重担。若不这么做,则可能导致非常复杂的编译器诊断。

全库范围的概念

包含分配信息的类类型

封装访问/寻址,分配/解分配,以及对象的构造/析构的策略。

可能需要分配或释放内存的每个标准库组件,从 std::stringstd::vectorstd::array 以外的所有容器,到 std::shared_ptrstd::function,都通过 Allocator分配器 进行这些操作:分配器是满足下列要求的类类型对象。

某些要求是可选的:模板 std::allocator_traits 为所有可选要求提供默认实现,且所有标准库容器和其他具分配器类,都是通过 std::allocator_traits 访问分配器,而并不直接访问。

要求

给定

  • 无 cv 限定的对象类型 T
  • 针对类型 T分配器 (Allocator) 类型 A
  • A 类型的对象 a
  • B,为针对某个无 cv 限定的对象类型 U 的对应分配器 (Allocator) 类型(重绑定 A 所得)
  • B 类型的对象 b
  • allocator_traits<A>::pointer 类型的值 ptr,由调用 allocator_traits<A>::allocate() 所获得
  • allocator_traits<A>::const_pointer 类型的值 cptr,从 ptr 转换而获得
  • allocator_traits<A>::void_pointer 类型的值 vptr,从 ptr 转换而获得
  • allocator_traits<A>::const_void_pointer 类型的值 cvptr,从 cptrvptr 转换而获得
  • xptr,为针对某各无 cv 限定对象类型 X 的可解引用指针
  • r,为从表达式 *ptr 获得的 T 类型的左值
  • allocator_traits<A>::size_type 类型的值 n
表达式要求返回类型
A::pointer (可选)满足可空指针 (NullablePointer) 、遗留随机访问迭代器 (LegacyRandomAccessIterator) 及遗留连续迭代器 (LegacyContiguousIterator) (见下文缀饰指针)
A::const_pointer (可选)A::pointer 可转换为 A::const_pointer可空指针 (NullablePointer) 、遗留随机访问迭代器 (LegacyRandomAccessIterator) 及遗留连续迭代器 (LegacyContiguousIterator)
A::void_pointer (可选)A::pointer 可转换为 A::void_pointer

B::void_pointerA::void_pointer 是同一类型。满足可空指针 (NullablePointer)

A::const_void_pointer (可选)A::pointerA::const_pointerA::void_pointer 可转换到 A::const_void_pointer

B::const_void_pointerA::const_void_pointer 是同一类型。满足可空指针 (NullablePointer)

A::value_type类型 T
A::size_type (可选)A::size_type 能表示 A 所能分配的最大对象的大小无符号整数类型
A::difference_type (可选)A::difference_type 能表示任意两个指向 A 所分配对象的指针之间的差有符号整数类型
A::template rebind<U>::other (可选)[1]对于任何 UB::template rebind<T>::otherA类型 B
*ptrT&
*cptr*cptr 与 *ptr 标识同一对象const T&
ptr->m若 (*ptr).m 良构,则与 (*ptr).m 相同T::m 的类型
cptr->m若 (*cptr).m 良构,则与 (*cptr).m 相同T::m 的类型
static_cast<A::pointer>(vptr)static_cast<A::pointer>(vptr) == ptrA::pointer
static_cast<A::const_pointer>(cvptr)static_cast<A::const_pointer>(cvptr) == cptrA::const_pointer
std::pointer_traits<A::pointer>::pointer_to(r)A::pointer
a.allocate(n)分配适合 nT 类型对象的存储,但不构造它们。可以抛异常。A::pointer
a.allocate(n, cvptr) (可选)a.allocate(n) 相同,但可以以未指明的方式使用 cvptr(从 a.allocate() 获得的指针或 nullptr_t)以协助局部性A::pointer
a.deallocate(ptr, n)解分配 ptr 所指向的存储,该指针必须是先前从对 allocate 的调用获得的指针,且未因中间对 deallocate 的调用而失效。n 必须匹配先前传递给 allocate 的值。不抛异常。(不使用)
a.max_size() (可选)能传递给 A::allocate() 的最大值A::size_type
a1 == a2仅若分配器 a1 分配的存储能通过 a2 解分配才返回 true。建立自反、对称和可传递关系。不抛异常。bool
a1 != a2与 !(a1==a2) 相同bool
A a1(a)

A a1 = a

复制构造 a1 以满足 a1 == a。不抛异常。(注意:所有分配器 (Allocator) 也都满足可复制构造 (CopyConstructible) )
A a(b)构造满足 B(a)==b 和 A(b)==a 的 a。不抛异常。(注意,这意味着所有因 rebind 相关联的分配器都彼此维护资源,例如内存池)
A a1(std::move(a))

A a1 = std::move(a)

构造 a1 使之等于 a 之前的值。不抛异常。 a 的值不变且 a1 == a。 (C++17 起)
A a(std::move(b))构造 a 使之等于 A(b) 之前的值。不抛异常。
a.construct(xptr, args) (可选)在先前分配的存储中由 xptr 所指向的地址上,以 args 为构造函数实参构造一个 X 类型的对象
a.destroy(xptr) (可选)析构 xptr 所指向的 X 类型的对象,但不解分配任何存储。
a.select_on_container_copy_construction() (可选)提供一个 A 实例,以被从当前正使用 a 的容器所复制构造的容器使用。通常要么返回 a 的副本,要么为默认构造的 A()A
A::propagate_on_container_copy_assignment (可选)若在使用 A 类型的分配器的容器被复制赋值时需要复制该分配器,则为 true。注意,若源和目标容器的分配器比较不相等,则复制赋值时必须用旧分配器解分配目标的内存,再在进行各元素(和分配器)的复制之前用新分配器分配内存std::true_type 或 std::false_type 或从它派生的类型
A::propagate_on_container_move_assignment (可选)若在使用 A 类型的分配器的容器被移动赋值时需要移动该分配器,则为 true。若此成员是 false 且源和目标容器的分配器比较不相等,则移动赋值不能夺取源内存的所有权,而必须逐个进行元素的移动赋值或移动构造,按需调整其自身内存的大小。std::true_type 或 std::false_type 或从它派生的类型
A::propagate_on_container_swap (可选)若在使用 A 类型的分配器的两个容器进行交换时需要交换分配器,则为 true。若此成员是 false 且两个容器的分配器比较不相等,则容器交换的行为未定义。std::true_type 或 std::false_type 或从它派生的类型
A::is_always_equal (C++17 起) (可选)若两个 A 类型的分配器始终比较相等则为 true。若不提供,则 std::allocator_traits 默认它等于 std::is_empty<A>::typestd::true_type 或 std::false_type 或从它派生的类型

注:

  1. ↑ 仅当此分配器是 SomeAllocator<T, Args> 形式的模板(其中 Args 是零或更多额外的模板类型形参)时,rebind 才是可选的(由 std::allocator_traits 提供)。

另外,为使类型 A 满足分配器 (Allocator)

  • A::propagate_on_container_copy_assignment::valuetrue,则 A 必须满足可复制赋值 (CopyAssignable) 且复制操作必须不抛异常
  • A::propagate_on_container_move_assignment::valuetrue,则 A 必须满足可移动赋值 (MoveAssignable) 且移动操作必须不抛异常。
  • A::propagate_on_container_swap::valuetrue,则 A 的左值必须可交换 (Swappable) 且交换操作必须不抛异常
(C++17 起)

给定

  • X::void_pointerX::const_void_pointerX::pointerX::const_pointer 类型的对象 x1x2,类型可以不同

则,当且仅当 x1x2 分别都能用只使用这四种类型的 static_casts 的序列显式转换为 X::const_pointer 类型的对象 px1px2,且表达式 px1 == px2 求值为 true,则 x1x2值等价的指针值

给定

  • X::void_pointer 类型的对象 w1w2

则对于表达式 w1 == w2 与 w1 != w2,任一或两个对象都可由值等价X::const_void_pointer 类型的对象所替换,而语义没有变化。

给定

  • X::pointer 类型的对象 p1p2

则,对于表达式 p1 == p2、p1 != p2、p1 < p2、p1 <= p2、p1 >= p2、p1 > p2、p1 - p2},任一或两个对象都可由值等价X::const_pointer 类型的对象所替换,而语义没有变化。

上述要求使得比较容器 (Container) 的 iterator 和 const_iterator 成为可能。

(C++14 起)

分配器完整性要求

若无论 T 是否为完整类型下列二者皆为真,则针对类型 T 的分配器类型 X 还额外满足分配器完整性要求

  • X 是完整类型
  • value_type 之外,所有 std::allocator_traits<X> 的成员都是完整类型。
(C++17 起)

缀饰指针

当成员类型 pointer 不是原生指针时,它通常被称为“缀饰指针(fancy pointer)”。这种指针曾为支持分段内存架构而引入,并在当今用于访问在某些不同于原生指针所访问的同质虚拟地址空间的地址空间中所分配的对象。缀饰指针的一个实例是映射的不依赖地址指针 boost::interprocess::offset_ptr,它使得在共享内存和在每个进程中映射到不同地址的映射到内存文件中,分配 std::set 一类的基于结点的数据结构可行。通过类模板 std::pointer_traits,缀饰指针可以独立于提供它们的分配器而使用。

标准库

下列标准库组件满足分配器 (Allocator) 要求:

allocator

默认的分配器
(类模板)

scoped_allocator_adaptor

(C++11)

为多级容器实现的多级分配器
(类模板)

polymorphic_allocator

(C++17)

以 std::memory_resource 构造,支持基于它的运行时多态的分配器
(类模板)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/619917.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode264. 丑数 II(相关话题:多重指针动态规划)

题目描述 给你一个整数 n &#xff0c;请你找出并返回第 n 个 丑数 。丑数 就是质因子只包含 2、3 和 5 的正整数。 示例 1&#xff1a; 输入&#xff1a;n 10 输出&#xff1a;12 解释&#xff1a;[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。示例 2&am…

【Sharding-Sphere 整合SpringBoot】

Sharding-Jdbc在3.0后改名为Sharding-Sphere。Sharding-Sphere相关资料&#xff0c;请自行网上查阅&#xff0c;这里仅仅介绍了实战相关内容&#xff0c;算是抛砖引玉。 Sharding-Sphere 整合SpringBoot 一、项目准备二、项目实战1. pom.xml及application.yml2. OrderInfoCont…

串行Nor Flash的结构和参数特性

文章目录 引言1、Nor Flash的结构2、Nor Flash的类别3.标准Serial Nor Flash的特征属性1.Wide Range VCC Flash2.Permanent Lock3.Default Lock Protection4.Standard Serial Interface5.Multi-I/O6.Multi-I/O Duplex (DTR)7.XIP&#xff08;片上执行&#xff09; 4.标准Serial…

前端架构师需要具备哪些能力?

我们先看看前端架构师的招聘要求。 公司一 工作职责 1、参与项目需求分析评审&#xff0c;负责核心功能详细设计&#xff1b; 2、参与技术调研&#xff0c;负责解决开发过程中的技术难点问题&#xff1b; 3、协助制定前端开发规范&#xff0c;核心代码开发&#xff1b; 4、负…

Java内置锁:深度解析Lock接口中lock方法和lockInterruptibly方法

Java11中的Lock接口提供lock()和lockInterruptibly()两种锁定方法&#xff0c;用于获取锁&#xff0c;但处理线程中断时有所不同&#xff0c;lock()使线程等待直到锁释放&#xff0c;期间无视中断&#xff1b;而lockInterruptibly()在等待中若收到中断请求&#xff0c;会立即响…

倍福PLC控制器开发环境介绍

倍福PLC控制器是一款功能强大、易于使用的可编程逻辑控制器&#xff0c;广泛应用于各种工业自动化控制系统中。为了充分发挥倍福PLC控制器的功能&#xff0c;需要使用合适的开发环境。下面将介绍倍福PLC控制器的开发环境&#xff0c;主要包括软件安装与配置、工程创建与管理、编…

“超人练习法”系列08:ZPD 理论

01 先认识一个靓仔 看过 Lev Vygotsky 这个人的书吗&#xff1f;他是一位熟练心理学家&#xff0c;对人们习得技能的方式非常感兴趣&#xff0c;但他 37 岁的时候就因肺炎英年早逝了。 他认为社会环境对学习有关键性的作用&#xff0c;认为社会因素与个人因素的整合促成了学习…

MySQL修改登录密码

适用于可以登录进入mysql数据库&#xff0c;想修改密码或者提示密码过期 ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement 如果忘记密码可以看Linux系统MySQL忘记登录密码-CSDN博客这篇文章 方法一&#xff…

element ui el-table展示列表,结合分页+过滤功能

vueelement-ui实现的列表展示&#xff0c;列表分页&#xff0c;列表筛选功能 1&#xff0c;分页器 el-table模块下面是分页器代码 <el-pagination></el-pagination> <el-table></el-table> <!-- 分页器 --><div class"block" st…

力扣每日一练(24-1-13)

如果用列表生成式&#xff0c;可以满足输出的型式&#xff0c;但是不满足题意&#xff1a; nums[:] [i for i in nums if i ! val]return len(nums) 题意要求是&#xff1a; 你需要原地修改数组&#xff0c;并且只使用O(1)的额外空间。这意味着我们不能创建新的列表&#xff…

【QT】标准对话框

目录 1 概述 2 QFileDialog对话框 1.选择打开一个文件 2.选择打开多个文件 3&#xff0e;选择已有目录 4&#xff0e;选择保存文件名 3 QColorDialog对话框 4 QFontDialog对话框 5 QInputDialog标准输入对话框 1.输入文字 2&#xff0e;输入整数 3&#xff0e;输入…

Python教程(23)——Python类中常用的特殊成员

在Python中&#xff0c;类特殊成员是指以双下划线开头和结尾的属性和方法&#xff0c;也被称为魔术方法&#xff08;Magic methods&#xff09;或特殊方法&#xff08;Special methods&#xff09;。这些特殊成员在类的定义中具有特殊的语法和功能&#xff0c;用于实现对象的特…

【PlantUML】-类图-布局,如何改变元素位置

写在前面 PlantUML属于自动布局。掌握好&#xff0c;是一件利器&#xff0c;掌握不好&#xff0c;就会不知其所以然。尤其在布局方面&#xff0c;因为它的布局可能会和你想的不太一样。本篇文章以例子为基础&#xff0c;简单地说几个在实际应用过程中摸索出来的原则。相信看完这…

【猫头虎分享】全面揭秘鸿蒙4.0:华为的技术革新与市场影响

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

逆变器3前级推免(高频变压器)

一节电池标压是在2.8V—4.2V之间&#xff0c;所以24V电压需要大概七节电池串联。七节电池电压大概在19.6V—29.4V之间。 从24V的电池逆变到到220V需要升压的过程。那么我们具体需要升压到多少&#xff1f; 市电AC220V是有效值电压&#xff0c;峰值电压是220V*1.414311V 如果…

ssm基于Javaweb的物流信息管理系统的设计与实现论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统物流信息管理难度大&#xff0c;容错率低&#xff0c;管理…

Unity的Camera类——视觉掌控与深度解析(下)

前言 欢迎阅读本篇博客&#xff0c;这章我们将深入探讨 Unity 游戏引擎中 Camera 类的委托和枚举。摄像机在游戏开发中扮演着关键角色&#xff0c;它不仅定义了玩家视角的窗口&#xff0c;还影响着游戏的视觉表达和整体体验。理解和正确使用 Camera 类的枚举和委托&#xff0c…

【mmseg】‘SegDataPreProcessor is not in the model registry问题解决

问题描述&#xff1a; 在使用mmseg的模型进行推理导出为torchscript时出错&#xff1a; KeyError: "class EncoderDecoder in mmseg/models/segmentors/encoder_decoder.py: SegDataPreProcessor is not in the model registry. Please check whether the value of SegDat…

数据结构——排序算法之快速排序

个人主页&#xff1a;日刷百题 系列专栏&#xff1a;〖C/C小游戏〗〖Linux〗〖数据结构〗 〖C语言〗 &#x1f30e;欢迎各位→点赞&#x1f44d;收藏⭐️留言&#x1f4dd; ​ ​ 前言&#xff1a; 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。 基本思想&…

设计模式-工厂方法模式

一 设计模式-工厂方法模式 工厂方法模式&#xff08;Factory Method Pattern&#xff09;是一种常用的类创建型设计模式&#xff0c;它属于对象的创建型模式&#xff0c;主要用来封装对象的创建过程。在该模式中&#xff0c;一个抽象工厂定义了一个接口用于创建产品对象&#x…