ここに割り当てられているメモリの2種類があります。 unique_ptr
のためにvector
に割り当てられたメモリがあります(それほど多くはありませんが、unique_ptrあたりのポインタです)。そして、unique_ptr
によって管理されているオブジェクトの動的に割り当てられたメモリ。
を割り当てることはできませんそれぞれのオブジェクト内のオブジェクトに動的に割り当てられたメモリを個別に割り当てる必要があります。
しかし、あなたが原因複数のベクトル用のメモリの再割り当てを回避したい場合はinsert
あなたが最初に準備を行うことができます呼び出します。
vec.reserve(vec.size() + n);
私はそれはしかし3ほどの小さなn
のための任意の影響を与えることはないだろう。
さらに多くの問題点は、insert
ごとに、ベクトルがvector
のすべての内容を挿入ポイントの後に1つ移動しなければならないことです。移動するunique_ptr
は安いですが、それは追加することができます。
これは確かにクリーナーではありませんが、std::move_backward
を使用すると一度自分を動かすことができます。、サイズ必要にベクトルのサイズを変更するに沿って、すべての要素を移動してから、挿入したい要素で移動-割り当てるunique_ptr
:
auto prev_size = vec.size();
vec.resize(prev_size + 3);
auto prev_end = vec.begin() + prev_size;
std::move_backward(vec.begin(), prev_end, vec.end());
for (int n = 0; n != 3; ++n)
vec[n] = std::make_unique<int>(0);
別の、おそらくクリーナー、同じことを達成する方法を作成することです独自のカスタムinsert
のstd::vector::insert(const_iterator position, InputIterator first, InputIterator last);
過負荷で使用するために、前方反復子:
template<typename T>
struct UniquePtrInserter : std::iterator<
std::forward_iterator_tag,
std::unique_ptr<T>,
std::ptrdiff_t,
const std::unique_ptr<T>*,
std::unique_ptr<T>>{
int n_;
public:
explicit UniquePtrInserter<T>(int n = 0) : n_(n) {}
UniquePtrInserter<T>& operator++() {n_++; return *this;}
bool operator==(UniquePtrInserter<T> other) const {return n_ == other.n_;}
bool operator!=(UniquePtrInserter<T> other) const {return !(*this == other);}
std::unique_ptr<T> operator*() const {return std::make_unique<T>(); }
};
vec.insert(vec.begin(), UniquePtrInserter<int>(0), UniquePtrInserter<int>(3));
を避けるために'を持つことができます。あるいは、3要素配列を保持する 'std :: unique_ptr 'と、その配列への生ポインタを含む別々の 'std :: vector 'です。 –
generate_n
を使用することができます'std :: make_unique()'を呼び出すか、ポインタの別の配列/コンテナから移動します。それ以外の場合は、デザインを再考してください。例えば、3つの要素を持つ単一の 'std :: vector...または 'のstd :: generate_n( のstd ::サーター(VEC、vec.begin())、 3、 のstd ::バインド(のstd :: make_unique、0) );'しかし、私はwouldnそれを清潔にしてはいけません。 –
jrok