分配空 std::vector 与交换空 std::vector 相同吗?
Is assigning empty std::vector same as swaping for an empty std::vector?
C++ delete vector, objects, free memory 声明为了在清除 std::vector 后释放分配的堆内存,可以这样做:
vector<int>().swap(myVector);
说得有道理,但我想知道以下是否不会达到同样的效果。谁能告诉我有什么不同吗?
myVector = vector<int>();
这些备选方案之间没有显着差异。
但是,我推荐第三个选项,因为它对 reader:
更明显
myVector.clear();
myVector.shrink_to_fit();
Can someone tell me whether there's a difference?
如果myVector = vector<int>();
The old memory isn't necessarily deallocated(released).
但如果 vector<int>().swap(myVector);
old memory deallocation will happen.
根据标准,从右值赋值(即:移动赋值)(非std::array
)容器is not allowed to invoke the move constructor or assignment operators of T
unless the allocator for that container does not propagate on container move-assignment。这意味着 vector
此类分配器的唯一有效实现是销毁当前分配并采用右值中的分配。 std::allocator
确实在容器移动分配上传播,因此此类容器的任何移动分配都将强制采用右值的内容。
这是否意味着myVector = vector<int>();
保证采用空分配?不必要。 检测右值容器为空,销毁它自己的元素,但保留其内部分配供以后使用是完全有效的。
相比之下,vector::swap
的实现做同样的事情是不可行的。 iterator/pointer/reference 保存要求确保将一个容器中的对象 iterators/pointers/references 映射到另一个容器中的对象(只要分配器通过容器交换传播允许这样做)。这意味着两个对象中的分配实际上必须交换,即使其中一个没有分配。赋值没有这样的迭代器保存要求。
话虽这么说,假设实现将是病态的并积极尝试避免您尝试删除容器的分配并不是一个好主意。同样,对 shrink_to_fit
的调用不能保证容量会改变......但是 没有 的实现将是一个非常愚蠢的实现。
所以有人可能会争辩说,最好的代码应该是能够清楚地解释正在发生的事情的代码。 swap
是一个成语,您必须让某人解释为什么要在这样的纯右值上使用它。 clear()
后跟 shrink_to_fit
使您从文档中清楚地知道您在做什么;无需解释。
所以也许可以考虑这样做。
C++ delete vector, objects, free memory 声明为了在清除 std::vector 后释放分配的堆内存,可以这样做:
vector<int>().swap(myVector);
说得有道理,但我想知道以下是否不会达到同样的效果。谁能告诉我有什么不同吗?
myVector = vector<int>();
这些备选方案之间没有显着差异。
但是,我推荐第三个选项,因为它对 reader:
更明显myVector.clear();
myVector.shrink_to_fit();
Can someone tell me whether there's a difference?
如果myVector = vector<int>();
The old memory isn't necessarily deallocated(released).
但如果 vector<int>().swap(myVector);
old memory deallocation will happen.
根据标准,从右值赋值(即:移动赋值)(非std::array
)容器is not allowed to invoke the move constructor or assignment operators of T
unless the allocator for that container does not propagate on container move-assignment。这意味着 vector
此类分配器的唯一有效实现是销毁当前分配并采用右值中的分配。 std::allocator
确实在容器移动分配上传播,因此此类容器的任何移动分配都将强制采用右值的内容。
这是否意味着myVector = vector<int>();
保证采用空分配?不必要。 检测右值容器为空,销毁它自己的元素,但保留其内部分配供以后使用是完全有效的。
相比之下,vector::swap
的实现做同样的事情是不可行的。 iterator/pointer/reference 保存要求确保将一个容器中的对象 iterators/pointers/references 映射到另一个容器中的对象(只要分配器通过容器交换传播允许这样做)。这意味着两个对象中的分配实际上必须交换,即使其中一个没有分配。赋值没有这样的迭代器保存要求。
话虽这么说,假设实现将是病态的并积极尝试避免您尝试删除容器的分配并不是一个好主意。同样,对 shrink_to_fit
的调用不能保证容量会改变......但是 没有 的实现将是一个非常愚蠢的实现。
所以有人可能会争辩说,最好的代码应该是能够清楚地解释正在发生的事情的代码。 swap
是一个成语,您必须让某人解释为什么要在这样的纯右值上使用它。 clear()
后跟 shrink_to_fit
使您从文档中清楚地知道您在做什么;无需解释。
所以也许可以考虑这样做。