在vector.reserve()之后vector.data()不为空吗?

Posted

技术标签:

【中文标题】在vector.reserve()之后vector.data()不为空吗?【英文标题】:Is vector.data() not null after vector.reserve()? 【发布时间】:2020-08-10 10:18:41 【问题描述】:

vec.data() usually is &vec[0] vec.empty() 除外。在后一种情况下,vec.data() 可能是nullptr

问题:如果我以足够的大小调用vec.reserve,我知道&vec[0] 不会再改变了。但是对于最初为空的向量的边缘情况,我是否可以依靠 vec.data() 也很稳定?

基本原理:在 ctor 中,我想将 const T* const 初始化为 vec.data()。没有一个班级成员会让vec 增长到超过保留的大小。我可以添加一个临时的单个元素,这样我就可以写&vec[0],但这似乎有点做作。

【问题讨论】:

【参考方案1】:

我对此的看法是,不,空向量并不能保证 vector::data 即使在调用 vector::reserve 之后也会返回底层缓冲区。

推理

AFAIK vector::data() 是在 issue n. 464 中提出的,看起来完全相同的提议措辞已被标准接受。

讨论摘录:

为了给 vector 和 map 增加一点便利,我们应该 考虑添加

    添加 vector::data() 成员(常量和非常量版本)语义: 如果(空())返回0;否则返回缓冲区_; ...

理由:

要获得指向向量缓冲区的指针,必须使用 运算符(可以为空向量提供未定义的行为)或 at() (如果向量为空,则会抛出)。

...

Standard draft - 22.3.11.4:

返回:一个使得 [data(), data() + size()) 有效的指针 范围。对于非空向量,data() == addressof(front())。

作者似乎希望在他们的基本原理中始终为空容器返回nullptr,这就是您的情况。但提议和接受的措辞却模棱两可。

最后一行是vector::data(),因为空向量仍然返回不确定的值。

标准的其他部分 ([22.3.11.3]) 一起保证缓冲区在调用 reserve 后仍然存在,但 ::data 仍然可能返回,例如nullptr 根据原始讨论。

安全的方式

唯一安全的方法似乎是您的解决方案:

    添加虚拟元素 存储vector::data() 返回值,因为它现在保证为&v[o]。 删除虚拟元素。

注意,2.,3。无法兑换,data 可以再次开始退货。

我不知道以下措辞会导致任何不利影响。

返回:一个使得 [data(), data() + size()) 有效的指针 范围。对于非零容量向量,data() == addressof(front()) 调用时向量的大小至少为 1。

【讨论】:

以上是关于在vector.reserve()之后vector.data()不为空吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 vector::resize() 和 vector::reserve() 之间选择

std::vector::resize() 与 std::vector::reserve()

vector reserve与resize区别

为啥 fill_n() 不适用于 vector.reserve()?

libxx.so: undefined reference, vector.reserve(n)

libxx.so: undefined reference, vector.reserve(n)