std::vector 是一个非常规类型,因为它的赋值运算符移动了它的成员的位置
is std::vector a non regular type due to its assignment operator moving the location of its members
向量以一种方式包装它的数组,它假装数组的元素是向量本身的成员。这就是为什么不能修改 const 向量的数组元素的原因。该向量还允许您访问其数组元素的地址。但是,如果我得到一个指向向量的数组元素的指针(它是向量本身的一个元素),然后我分配给向量,我的指针就不再定义为指向向量的一个元素。 push_back()
或类似的东西使指针无效是有意义的,因为没有人说 push_back()
没有对向量的元素做一些荒谬的事情。
任何常规类型都会让我指向其元素的指针在赋值后保持有效。所以,并不是说没有变通办法,而是说这不会使 vector 成为非常规类型吗?
std::string
和标准中的许多其他 list/storage 类型也是如此。
已编辑:当我说具体类型时,指的是常规类型。
编辑,还有一点:所以,在 c 中,如果你得到一个指向结构成员的指针,分配给该结构实际上不能改变对象的位置,因为你不能假装一个数组元素是结构的一部分。然而,在向量中,这个规则被打破了。成员是对象的成员,因为它从字面上与相同的对象名称相关联,并且在对象被销毁之前一直如此。所以一般的操作应该都改不了这样的。
C++ 中常规类型的概念来自 Stepanov 的编程基础。它基本上是一个类型的 reasonable/useful 概念列表。比如要支持相等、赋值,赋值要有post条件,赋值变量和原变量比较相等(当然,这是复制赋值,不是移动赋值)。
但是,规律性不包括您所描述的概念。具体是完全不同的东西,它基本上只是任何 class 可以实际实例化的东西,即没有纯虚拟方法。
Stepanov 确实有一个与您所描述的内容相关的 class化验。我手边没有我的副本,但我认为他将其称为内部与外部:这是一个问题,即包含该类型实例的位是否实际上包含该值的所有信息。 vector 是外部的,因为通常构成 vector 本身的三个指针并不能完全描述它,堆上还有一些东西是 vector 表示的一部分,即使它不包含 "inside" 实际的 vector 实例。
出现您描述的问题是因为 vector 是外部的。任何时候你使用直接指向类型外部部分的指针,然后对该类型执行操作时,这些指针可能会失效。然而,具有像 int 这样的简单成员的结构是内部的,所有信息都包含在结构本身中。这会导致行为差异。
如果你想要一个动态大小的数组类型,你基本上必须使用堆,使用堆意味着你的类型将是外部的,此时你会面临这些问题。这就是为什么所有标准容器都有关于何时可以使迭代器失效的详细描述。
向量以一种方式包装它的数组,它假装数组的元素是向量本身的成员。这就是为什么不能修改 const 向量的数组元素的原因。该向量还允许您访问其数组元素的地址。但是,如果我得到一个指向向量的数组元素的指针(它是向量本身的一个元素),然后我分配给向量,我的指针就不再定义为指向向量的一个元素。 push_back()
或类似的东西使指针无效是有意义的,因为没有人说 push_back()
没有对向量的元素做一些荒谬的事情。
任何常规类型都会让我指向其元素的指针在赋值后保持有效。所以,并不是说没有变通办法,而是说这不会使 vector 成为非常规类型吗?
std::string
和标准中的许多其他 list/storage 类型也是如此。
已编辑:当我说具体类型时,指的是常规类型。
编辑,还有一点:所以,在 c 中,如果你得到一个指向结构成员的指针,分配给该结构实际上不能改变对象的位置,因为你不能假装一个数组元素是结构的一部分。然而,在向量中,这个规则被打破了。成员是对象的成员,因为它从字面上与相同的对象名称相关联,并且在对象被销毁之前一直如此。所以一般的操作应该都改不了这样的。
C++ 中常规类型的概念来自 Stepanov 的编程基础。它基本上是一个类型的 reasonable/useful 概念列表。比如要支持相等、赋值,赋值要有post条件,赋值变量和原变量比较相等(当然,这是复制赋值,不是移动赋值)。
但是,规律性不包括您所描述的概念。具体是完全不同的东西,它基本上只是任何 class 可以实际实例化的东西,即没有纯虚拟方法。
Stepanov 确实有一个与您所描述的内容相关的 class化验。我手边没有我的副本,但我认为他将其称为内部与外部:这是一个问题,即包含该类型实例的位是否实际上包含该值的所有信息。 vector 是外部的,因为通常构成 vector 本身的三个指针并不能完全描述它,堆上还有一些东西是 vector 表示的一部分,即使它不包含 "inside" 实际的 vector 实例。
出现您描述的问题是因为 vector 是外部的。任何时候你使用直接指向类型外部部分的指针,然后对该类型执行操作时,这些指针可能会失效。然而,具有像 int 这样的简单成员的结构是内部的,所有信息都包含在结构本身中。这会导致行为差异。
如果你想要一个动态大小的数组类型,你基本上必须使用堆,使用堆意味着你的类型将是外部的,此时你会面临这些问题。这就是为什么所有标准容器都有关于何时可以使迭代器失效的详细描述。