我正在使用STL库,我的目标是最小化数据重新分配的情况。 我在想,是吗
如果大小没有改变,那么std :: vector :: assign(size_type n,const value_type& val)
重新分配数据,或者实际上只是分配新值(例如,使用operator =)?
http://www.cplusplus.com/的STL文档如下(C ++ 98):
在填充版本(2)中,新内容是n个元素,每个元素都初始化为val的副本。 如果发生重新分配,则使用内部分配器分配所需的存储。
在调用之前容器中保存的任何元素都被销毁并被新构造的元素替换(不会发生元素的赋值)。 如果 - 并且仅在新的矢量大小超过当前矢量容量时,这会导致分配的存储空间的自动重新分配。
短语“没有元素的分配发生”使这一切都有点令人困惑。
所以例如,我想要一个类的向量(例如,OpenCV的cv :: Vec3i)。这是不是意味着
编辑:在这种情况下使用assign的全部目的是将向量中的所有值都设置为0(如果我有std :: vector< cv :: Vec3i> v)。它会做很多次。 std :: vector本身的大小不会改变。
我想做的事情(以较短的方式)如下:
for(int i=0; i<v.size(); i++)
for(int j=0; j<3; j++)
v[i][j] = 0;
现在我对 C ++ 98
感兴趣答案 0 :(得分:1)
std::vector.assign(...)
如果不需要增长它,则不会重新分配该向量。但是,它必须复制实际元素。
如果您想知道标准保证的内容,请查看标准:C++11 standard plus minor editorial changes.
答案 1 :(得分:1)
我假设你有一个载有一些数据的向量,你在其上调用一个赋值,这将:
因此,如果您的类分配了一些内存,您必须:
当大小超过分配的内存(向量容量)时,会发生重新分配。您可以通过调用reserve()来阻止这种情况。但是我认为assign()足够聪明,可以在开始填充向量之前以及在清除之后分配它所需的所有内存(如果这比已经分配的内存多)。
您可能希望避免重新分配,因为它们的成本,但如果您试图避免它们因为您的对象无法正确处理,那么我强烈建议您不要将它们放在矢量中。
答案 2 :(得分:1)
assign
的语义以一种非常直接的方式定义为标准:
void assign(size_type n,const T&amp; t);
效果:
erase(begin(), end());
insert(begin(), n, t);
这意味着首先会调用元素的析构函数。 t
的副本是在元素结束的生命周期之后留下的原始存储空间中创建的。
要求是value_type
是MoveAssignable
(因为erase
没有擦除到容器的末尾并且需要将元素移到开头)。
insert
重载要求value_type
为CopyInsertable
和CopyAssignable.
无论如何,vector无视你的班级如何管理自己的资源。那就是你要照顾的。见The Rule of Three.
答案 3 :(得分:0)
与vector::resize
方法的情况一样,
std::vector::assign(size_type n, const value_type& val)
会将每个元素初始化为“val”的副本。我更喜欢使用resize
,因为它最大限度地减少了对象实例/破坏的数量,但它也是如此。如果要最小化数据realloc,请使用resize
,但请记住以下内容:
虽然对某些数据结构这样做是安全的,但请注意,分配/推送包含指向动态分配数据的指针的类的元素(例如在构造函数中使用new
)可能会造成严重破坏。
如果您的类动态分配数据,那么您应该重新实现YourClass::operator=
以将数据复制到新对象而不是复制指针。
希望它有所帮助!