Basically, you are asking what happens when you do the following:
vector<int> v;
v.reserve(100);
We can look at what libstdc++ does in this case as an example.
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;
}
The important call here is _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;
}
The important call here is 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;
}
This is calling construct. As you can see, it is using the copy constructor.
void construct ( pointer p, const_reference val ) {
new ((void*)p) T (val);
}
Therefore, when a reallocate happens, every element in the vector has the copy constructor called on it.