制作 std::矢量容量>=N 和大小=0 的最佳方法是什么?
the best way to make a std::vector capacity>=N and size=0?
给定一个大小和容量可以任意的std::vector
,将其大小更改为 0 并将容量更改为至少 N(给定数字(的最佳实践是什么?
我的直接想法是:
void f(vector<int> &t, int N)
{
t.clear();
t.reserve(N);
}
但我注意到
不能保证会发生重新分配,并且向量容量为 不保证会改变(当调用 std::vector::clear 时(。
所以我想知道当源容量大于给定的 N 时如何避免重新分配?
大小更改为 0 并将容量更改为 N(给定数字(的最佳实践是什么?我的直接想法是:...
你的直接想法是正确的,也是最简单的选择。虽然是迂腐的,reserve
将容量更改为大于或等于给定的数字;不能保证相等(但是,如果以前的容量较小,我测试过的所有实现都会精确地分配给定的数量(。
所以我想知道当源容量大于给定的 N 时如何避免重新分配?
通过使用标准库实现,该实现已选择在调用clear
时不释放内存(即任何符合标准标准的实现,如此处的答案所示(。
另一种保证方法(尽管这似乎没有必要,因为尽管 cplusplus.com 的措辞很弱,但应该保证上述内容(没有重新分配(在N > t.capacity()
的情况下(:由于向量包含简单的整数,并且您似乎知道将有多少元素(因为您知道要保留(,您可以简单地调用t.resize(N)
(在大小较大的情况下删除多余的元素(,而无需清除向量, 然后继续覆盖现有元素,而不是推送新元素。
当然,这意味着您将无法观察到已覆盖的元素数量,因此此方法不适用于所有用例。如果您只是想用一个简单的循环填充向量,那很好。
如果新大小可能大于旧大小,并且您希望不要过度分配,则可能需要在调整大小之前进行保留。这是因为大多数实现在保留时分配确切的数量(如我所提到的(,但在调整大小时使用乘法策略(据我所知,这些行为都不能保证,但我使用的实现与这种行为一致(。
最好的方法可能是你当前的代码。
不幸的是,该标准允许实现具有容量只能增长的容器。在这种情况下,您的代码将仅保证容量至少为N。如果初始容量小于 N,则会发生重新分配,如果容量大于 N,则不会发生任何情况。这一点由标准保证,因为 C++17 的草案 4659 在 [vector.capacity] 上说(强调我的(:
void reserve(size_type n);
......
3 效果:通知向量计划的大小更改的指令,以便它可以管理存储 相应地分配。在 reserve(( 之后,capacity(( 大于或等于 reserve 的参数,如果 发生重新分配;否则等于 capacity(( 的先前值。发生重新分配 此时,当且仅当当前容量小于 reserve(( 的参数时。
和
void shrink_to_fit();
......
8 效果:shrink_to_fit 是一个将 capacity(( 减少到 size(( 的非约束性请求。[ 注:请求 不具有约束力,允许为特定于实现的优化留有余地。—尾注 ] 它没有 增加容量((,但可能会通过导致重新分配来减少容量((。
您无法保证容量正好为 N。相反,您的代码保证,如果初始容量大于 N in,则保持不变,并且不会发生重新分配。
编辑:至少自 C++11 年以来,此行为是稳定的(草案 n3337(
注意:这个答案回答了以下问题:
制作 std::矢量容量=N 和大小=0 的最佳方法是什么?
和
将其大小更改为 0 并将容量更改为 N(给定数字(的最佳做法是什么?
在此答案发布后,添加了对">= N"的更改并添加了避免重新分配的要求。
该标准没有提供任何保证的方式来实现这一目标。但你最好的机会是:
t.clear();
t.shrink_to_fit();
t.reserve(N);
建议进行第二次调用以减小容量以匹配当前大小(此时将0
(。
同样由实现自行决定的可能有效也可能无效的替代方法是:
t.swap( std::vector<int>{} );
t.reserve(N);
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 派生类销毁的最佳实践是什么
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 在reactor中存储eventHandlers的最佳方式是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 将一系列整数放入类的最佳方法是什么?
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 比较两个节点坐标的最佳方法是什么?
- 在nodejs中使用本机代码的最佳方法是什么?
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 在 c++ 中解析数据包数据的最佳方法是什么?
- 初始化数组、"memset"或" {//value} "的最佳方法是什么?
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 在向量中查找大于 0(或通常为 k)的最小元素的最佳方法是什么?