C ++ 11是否要求vector <int>将resize()中的元素归零?</int>

时间:2013-04-09 11:07:50

标签: c++ performance vector c++11

这个问题是关于new [] int和new [] int()的语义和性能的差异,以及在向allocator_traits :: construct添加ctor参数的完美转发时可能无意中创建的从第一个到第二个措辞的变化()。这个问题并不涉及一个非常明显的问题,即在向量的resize()构造的所有新元素上运行默认的ctor。

对我来说,在resize中清除内置类型向量的元素似乎是浪费。但是实现了VS2012以便调整大小(n),因此带有count参数的构造函数实际上将分配的值数组设置为0。

我也在标准中找到了对此的支持,(http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3485.pdf)但我认为它可能是错误的,因为它依赖于最近涉及完美转发的条款:

第507页:

template <class T, class... Args>
static void construct(Alloc& a, T* p, Args&&... args);

5 E ff ects:invokes

::new (static_cast<void*>(p)) T(std::forward<Args>(args)...).

并且因为新的int()必须根据同一文档的第191页第11条将值设置为0,否则向量中的浪费实现是正确的。

问题是标准委员会是否真的希望构造调用的空参数包导致从默认构造到基本类型的值构造的行为发生变化。

2 个答案:

答案 0 :(得分:6)

不,这不是一个错误。

标准的先前版本有resize(n)创建一个元素,然后将其复制到向量中的所有新位置。新的措辞是故意允许不可复制的类型,但只是可构造的。

答案 1 :(得分:5)

容器永远不会保持未初始化是不变的 宾语。这意味着任何增加尺寸的东西 容器必须以某种方式初始化所有新元素。 这是一个功能,而不是未初始化的缺陷访问 值是未定义的行为,您无法重新分配(或 insert)如果某些值未初始化。 E.g:

std::vector<int> v;
v.resize( 20 );
v.insert( v.begin(), 1 );

如果resize,最后一行会导致未定义的行为 没有初始化它创建的元素。