在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()
为啥 fill_n() 不适用于 vector.reserve()?