c++ - 达到容量时的向量元素重复
问题描述
在程序中如下:
#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)
需要:i
并且j
不是a
.
v.push_back( v.back() );
保证工作,我相信。请参阅DR#526说“vector::insert(iter, value)
必须工作,因为标准不允许它不工作。” push_back
应该出于同样的原因工作。
DR#2164中讨论了更广泛的问题类别,其中emplace
可能采用任意数量的参数,其中一些可能引用容器的元素和/或其子对象。共识似乎是应该需要实施才能使其发挥作用。
推荐阅读
- pandas - 根据年份添加行
- c# - ASP.NET Core Web API / Angular-在单个请求/事务中创建和设置关系
- oracle - Oracle Forms 6i 错误:201 Identifire 或表中没有列
- javascript - WordPress:显示时间但在未来
- node.js - Firestore 在多个文档 ID 中的位置
- ansible - 如何使用 Ansible 仅下载和解压缩 tarball 一次
- laravel-livewire - 如何在 livewire 日期选择器中设置属性?
- python - Python 类按顺序创建属性
- swift - 在 macOS 的 SwiftUI 中更改 TextEditor 背景颜色
- wordpress - 如何访问 WordPress 中的 category.php 页面?