2012-02-21 76 views
10

副本在阅读代码,我看到:交换向量与自身

vector<TypeA>(typeAObj).swap(typeAObj); 

我的问题是

为什么他们换一个向量与自身的副本?

+1

FWIW,[这是不_guaranteed_做任何事情](http://stackoverflow.com/questions/7829018/can-we-rely-on-the-reduce-capacity-trick)。 – 2012-02-21 15:12:34

+0

请注意,矢量不与*本身*交换,而是与本身的*副本*交换。 – 2012-02-21 15:14:31

+0

我写了关于副本的文章,Rawicki编辑了它)) – 2012-02-21 15:18:44

回答

12

在C++ 03中,这是缩小到适合的模式,其中向量类的接口中没有此类操作。代码的作用是创建一个副本(希望该向量的capacity将接近可用元素的数量),然后将其与原始向量交换。表达式完成后,临时(现在保存原始缓冲区)将被丢弃,并释放内存。

考虑:

std::vector<int> large; 
large.reserve(10000000); // might be the result of multiple push_back/erase 
// large.capacity() >= 10000000 
large.push_back(1);  // Make more explicit that 'large' might not be empty 
std::vector<int>(large).swap(large); 
// large.capacity() is hopefully closer to 1 

在C++ 11的矢量类型已被修改,以提供一个shrink_to_fit的操作,需要在该角色。重要的是要注意,旧模式和shrink_to_fit都不是绑定操作,也就是说,除了capacity() >= size()之外的操作之后,无法保证该向量的capacity

+0

谢谢大卫!我确信这是一些副作用的伎俩。 – 2012-02-21 15:12:11

+0

“*除了capacity()> = size()*”之外的操作之后,向量的容量无法保证......为什么会这样呢? – Nawaz 2012-02-21 15:15:20

+1

@Nawaz:就是这样。 C++标准明确指出* shrink_to_fit *是一个不具约束力的调用,并声明没有这种保证。在这种模式中,同样的情况发生,在标准中没有任何地方需要拷贝不具有相同的*容量*或甚至比原始对象更多。对'capacity()'的唯一要求是,由于显而易见的原因,它必须至少是size()。除此之外,这个习语在很多实现中都起作用,如果它比这个尺寸大得多,就会减少容量。 – 2012-02-21 15:18:53

8

我相信这是一种将矢量“缩小”到最小尺寸的方法。

vector<TypeA>(typeAObj)创建保留大小可能小于原始大小的矢量的副本。

因此用一个新的副本交换矢量可能是一种释放一些不受欢迎的内存的方法。