是STD :: Vector,由于其分配运算符移动其成员的位置,因此是一种非常规类型

is std::vector a non regular type due to its assignment operator moving the location of its members

本文关键字:类型 非常规 一种 位置 成员 Vector STD 于其 分配 移动 运算符      更新时间:2023-10-16

矢量以假装数组的元素是向量本身的成员的方式包装其数组。这就是为什么您无法修改const向量的数组元素的原因。向量还允许您访问其数组元素的地址。但是,如果我将指针指向向量的数组元素(这是向量本身的元素),然后将我的指针分配给向量,则我的指针不再定义为指向向量的元素。对于push_back()或类似的东西来说,指针无效是有意义的,因为没有人说push_back()对向量的元素没有荒谬的事情。

任何常规类型都会有我的指针在分配后保持有效。因此,不是没有解决方法,但这不会使矢量成为非规范类型吗?

std::string和标准中的许多其他列表/存储类型也是如此。

编辑:是指我说混凝土类型时常规类型。

编辑,再加上一个点:因此,在C中,如果您有一个指向结构的成员的指针,则分配给该结构的构造无法更改对象的位置,因为您无法假装数组要成为结构的一部分的元素。但是,在向量中,该规则被打破了。成员是对象的成员,因为它实际上与同一对象名称相关联,并且始终将直到对象被破坏为止。因此,没有常规操作应该能够更改这样的事情。

C 中常规类型的概念来自Stepanov的编程元素。它基本上是类型上合理/有用的概念的列表。例如,它应支持平等和分配,分配应具有以下后条件,即分配的变量与原始变量相等(当然,这是复制分配而不是移动分配)。

但是,规律性不包括您要描述的概念。混凝土是完全不同的事情,基本上只是任何可以实例化的类,即没有纯虚拟方法。

Stepanov确实具有与您所描述的相关的分类。我没有方便的副本,但我认为他将其称为内部与外部的副本:这是一个问题,即包含该类型实例的位实际上包括该值的所有信息。向量是外部的,因为通常构成向量本身的三个指针并未完全描述它,即使它没有包含在"内部"实际矢量实例中,堆上也有堆的内容。p>您要描述的问题是因为向量是外部的。每当您采用直接进入类型外部部件的指针,然后对该类型进行操作,这些指针可能会被无效。然而,具有简单成员的结构是内部的,所有信息都包含在结构本身内部。这会导致行为差异。

如果您想要动态尺寸的数组类型,则基本上必须使用堆,并且使用堆意味着您的类型将是外部的,此时您可以对这些问题开放。这就是为什么所有标准容器都详细描述了其迭代器何时无效的原因。