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

Ben*_*son 4 c++ performance vector c++11

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

对我来说,在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);
Run Code Online (Sandbox Code Playgroud)

5 E ff ects:invokes

::new (static_cast<void*>(p)) T(std::forward<Args>(args)...).
Run Code Online (Sandbox Code Playgroud)

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

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

Bo *_*son 6

不,这不是一个错误.

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


Jam*_*nze 5

容器永远不会保留未初始化的对象是一个不变量.这意味着任何增加容器大小的东西都必须以某种方式初始化所有新元素.这是一个功能,而不是缺陷访问未初始化的值是未定义的行为,如果某些值未初始化,则无法重新分配(或插入).例如:

std::vector<int> v;
v.resize( 20 );
v.insert( v.begin(), 1 );
Run Code Online (Sandbox Code Playgroud)

如果resize 尚未初始化它创建的元素,则最后一行将导致未定义的行为.