跳转到内容

更多 C++ 习惯用法/缩减至适合

来自 Wikibooks,开放书籍,开放世界

缩减至适合

[编辑 | 编辑源代码]

将容器的容量最小化,足以容纳现有范围。

也称为

[编辑 | 编辑源代码]

"交换至适合",由 Scott Meyers 在他的著作 "Effective STL" 中介绍。

标准库容器通常分配的内存量大于其实际元素数量。这种策略导致了一种优化,即在容器大小增加时节省了一些分配。另一方面,当容器大小减小时,容器中通常会有剩余容量。容器的剩余容量可能是对内存资源的不必要的浪费。缩减至适合习惯用法已被开发出来将额外的容量减少到所需的最小容量,从而节省内存资源。

解决方案和示例代码

[编辑 | 编辑源代码]

缩减至适合习惯用法与下面给出的示例一样简单。

std::vector<int> v;
//v is swapped with its temporary copy, which is capacity optimal
std::vector<int>(v).swap(v);

语句的前半部分 std::vector<int>(v) 创建了一个临时整型向量,它保证[1] 仅分配足够的内存来容纳参数 v 中的所有元素。语句的后半部分使用非抛出交换成员函数将临时向量与 v 交换。swap() 非常高效,仅仅相当于交换向量之间的指针。交换后,临时对象将超出范围并删除 v 最初持有的内存,而 v 保留了临时对象分配的内存,因此它刚好足以容纳 v 中的原始元素。

  1. ISO/IEC 14882:1998 似乎没有记录这种复制构造函数的行为。这种行为是在哪里保证的?

一个更可靠的解决方案(特别是对于 std::string,它可能使用引用计数来实现,但对于 std::vector 也是如此,其复制构造函数可能会复制另一个向量的额外容量[1])是使用“范围构造函数”而不是复制构造函数。

std::vector<int> v;
//v is swapped with its temporary copy, which is capacity optimal
std::vector<int>(v.begin(), v.end()).swap(v);
  1. http://www.aristeia.com/BookErrata/estl1e-errata.html(搜索“string(s.begin(), s.end()).swap(s)”)

C++11 中的解决方案

[编辑 | 编辑源代码]

在 C++11 中,一些容器将此习惯用法声明为函数shrink_to_fit(),例如 vector、deque、basic_string。shrink_to_fit()是一个非约束请求,用于将capacity()减少到size().

已知用途

[编辑 | 编辑源代码]
[编辑 | 编辑源代码]

参考文献

[编辑 | 编辑源代码]
华夏公益教科书