如果 std::vector::resize 的 size 参数等于当前大小怎么办?

Posted

技术标签:

【中文标题】如果 std::vector::resize 的 size 参数等于当前大小怎么办?【英文标题】:What if size argument for std::vector::resize is equal to the current size? 【发布时间】:2019-04-26 02:34:36 【问题描述】:

阅读有关vector::resize http://www.cplusplus.com/reference/vector/vector/resize/的手册

它只说明如果大小更大或更小会发生什么,但没有说明如果大小相等会发生什么。是否保证在大小相等时不会重新分配数组并使迭代器无效?

我想避免一个分支并且只处理 2 个案例(>= 或 或 ==),但如果未定义调整到相同大小,那么我也必须检查该案例.

【问题讨论】:

鉴于“异常安全”部分中的信息,您可以放心地假设调整大小时没有重新分配大小等于向量的当前大小。 std::vector 类是模板类,因此您的计算机上有源代码。你可以自己找。或者您可以编写一个测试程序并对其进行调试。或者查看生成的汇编代码。或者制作一个类的向量,在调用复制构造函数和/或移动构造函数时打印信息,然后看看会发生什么。除此之外,我很确定在向量的实现中检查了这种情况,然后什么也没做。 不要阅读 cplusplus.com,众所周知它在某些情况下是错误的。 @n.m.请注意,在这种情况下,cppreference 也不清楚迭代器失效。它有一个注释,“当调整到更小的大小时,向量容量永远不会减少,因为这会使所有迭代器失效,......”但它没有明确说明哪些迭代器通常会失效 如果“相同大小的调整大小”有任何影响,那么整个 C++ 委员会和语言实现者就该退休了。 【参考方案1】:

这可能只是链接参考中的错误。标准说following:

void resize(size_type sz);

效果:如果是sz < size(),则从序列中删除最后一个size() - sz 元素。否则,将sz - size() 默认插入的元素附加到序列中。

由于在您的情况下sz - size()0,它不会做任何事情。

【讨论】:

【参考方案2】:

来自[vector]

效果:如果是sz < size(),则从序列中删除最后一个size() - sz 元素。否则,将sz - size() 默认插入的元素附加到序列中。

size() == sz的情况下,它在序列中插入0个元素,相当于什么都不做。

【讨论】:

【参考方案3】:

现在,对于不需要做任何事情并且实际上什么都不做的情况,可能大多数实现都足够智能。

但我问自己,你打算调用 resize,你为什么还要持有迭代器?基本上,您永远不应该长时间持有迭代器,尤其是当容器可能会调整大小时。只需以不需要将迭代器保持在调整大小点上的方式编写算法。

我在这里胡乱猜测,但也许你没有使用正确的容器,关于你想要达到的目标的更多上下文可能会产生更有用的答案。

【讨论】:

【参考方案4】:

您似乎在询问在调用 resize(size()) 时迭代器是否会失效。答案是否定的,迭代器不会失效。可能根本不会发生,但肯定不会发生迭代器失效,因为只有在必须重新分配存储时才会发生这种情况,如果调整大小是空操作,则永远不会发生这种情况。

【讨论】:

【参考方案5】:

std::vector<> 实现:

void resize(size_type __new_size)

    if (__new_size > size())
        _M_default_append(__new_size - size());
    else if (__new_size < size())
        _M_erase_at_end(this->_M_impl._M_start + __new_size);

所以,正如预期的那样:它什么都不做。

编辑: 取自我的 RHEL 服务器、g++ 和 C++ 库包版本 5.3。

【讨论】:

这是一种可能的实现(你应该提供一个参考,你从 btw 那里得到它),但你不能断定每个实现都必须这样做,只是因为这个实现 不幸的是,我的代码将使用不同的编译器为几种不同的架构进行编译,我不能依赖我在当前计算机上的头文件中可以找到的内容。

以上是关于如果 std::vector::resize 的 size 参数等于当前大小怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 std::vector::resize(n, src) 按值传递?

为啥在 C++11 中更改了 std::vector::resize 签名?

如果它是私有的,是不是可以从 main 调用方法?如果没有,怎么可能?

如果我爱你

如果复选框选中禁用其他,如果未选中启用所有 JavaScript?

如果新文件不存在则写入新文件,如果存在则追加到文件