基本的に、次のことを行うとどうなるかを尋ねています。
vector<int> v;
v.reserve(100);
この場合の libstdc++ の動作を例として見てみましょう。
template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>::reserve(size_type __n) {
if (__n > this->max_size())
__throw_length_error(__N("vector::reserve"));
if (this->capacity() >= __n)
return;
const size_type __old_size = size();
pointer __tmp = _M_allocate_and_copy(__n,
_GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_start),
_GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_finish));
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
this->_M_impl._M_start = __tmp;
this->_M_impl._M_finish = __tmp + __old_size;
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
}
ここで重要な呼び出しは_M_allocate_and_copy です
template<typename _ForwardIterator> pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first, _ForwardIterator __last) {
pointer __result = this->_M_allocate(__n);
std::__uninitialized_copy_a(__first, __last, __result, _M_get_Tp_allocator());
return __result;
}
ここで重要な呼び出しはstd::__uninitialized_copy_aです
template<typename _InputIterator, typename _ForwardIterator, typename _Allocator> _ForwardIterator __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _Allocator& __alloc) {
_ForwardIterator __cur = __result;
for (; __first != __last; ++__first, ++__cur)
__alloc.construct(&*__cur, *__first);
return __cur;
}
これはconstructを呼び出しています。ご覧のとおり、コピー コンストラクターを使用しています。
void construct ( pointer p, const_reference val ) {
new ((void*)p) T (val);
}
したがって、再割り当てが発生すると、ベクター内のすべての要素にコピー コンストラクターが呼び出されます。