达到容量时矢量元素重复

Vector element duplication when capacity is reached

本文关键字:元素 容量      更新时间:2024-09-22

在程序中如下所示:

#include <vector>
#include <memory>
#include <iostream>
int main()
{
std::vector<std::shared_ptr<int>> v{ std::make_shared<int>() };
for ( auto i = v.capacity() - v.size() + 1; i-- > 0; )
v.push_back( v.back() );
for ( auto i = v.capacity() - v.size() + 1; i-- > 0; )
v.insert( v.end(), --v.end(), v.end() );
for ( const auto & p : v )
{
std::cout << ( p ? "valid_ptr" : "null" ) << std::endl;
}
return 0;
}

一些编译器输出(Visual Studio,ellcc(:

valid_ptr
valid_ptr
valid_ptr

而其他(gcc、clang、icc(输出:

valid_ptr
valid_ptr
null

假设使用push_back复制最后一个元素总是正确工作,即使矢量达到其容量并需要重新分配,这是正确的吗?

同时,使用insert复制最后一个元素是一种未定义的行为还是特定于实现的行为?

v.insert( v.end(), --v.end(), v.end() )表现出未定义的行为,违反了标准库函数的先决条件。[sequence.reqmts]/4中的表87表示:

a.insert(p,i,j)
要求:ij不是a的迭代器。


v.push_back( v.back() );是保证工作的,我相信。参见DR#526说";vector::insert(iter, value)必须工作,因为标准没有允许它不工作"push_back应该出于同样的原因工作。

DR#2164中讨论了一类更广泛的问题,其中emplace可以采用任意数量的自变量,其中一些自变量可以引用容器的元素和/或其子对象。共识似乎是,应该要求执行才能使其发挥作用。