首页 > 解决方案 > 达到容量时的向量元素重复

问题描述

在程序中如下:

#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是未定义的或特定于实现的行为?

标签: c++vectorstlundefined-behavior

解决方案


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

a.insert(p,i,j)
需要: i并且j不是a.


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

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


推荐阅读