达到容量时向量元素复制
Vector element duplication when capacity is reached
程序中如下:
#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() )
表现出未定义的行为,违反了标准库函数的先决条件。 Table [sequence.reqmts]/4 中的 87 说,除此之外:
a.insert(p,i,j)
Requires: i
and j
are not iterators into a
.
我相信 v.push_back( v.back() );
一定会起作用。请参阅 DR#526 说“vector::insert(iter, value)
需要工作,因为标准不允许它不工作。” push_back
应该出于同样的原因工作。
DR#2164 中讨论了更广泛的 class 问题,其中 emplace
可能采用任意数量的参数,其中一些可能引用容器的元素 and/or 的子对象。共识似乎是需要实施才能使其发挥作用。
程序中如下:
#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() )
表现出未定义的行为,违反了标准库函数的先决条件。 Table [sequence.reqmts]/4 中的 87 说,除此之外:
a.insert(p,i,j)
Requires:i
andj
are not iterators intoa
.
我相信
v.push_back( v.back() );
一定会起作用。请参阅 DR#526 说“vector::insert(iter, value)
需要工作,因为标准不允许它不工作。” push_back
应该出于同样的原因工作。
DR#2164 中讨论了更广泛的 class 问题,其中 emplace
可能采用任意数量的参数,其中一些可能引用容器的元素 and/or 的子对象。共识似乎是需要实施才能使其发挥作用。