Doesn't mean that it isn't (in the context) expensive to construct, I
believe a copy means the contents are also copied?
You clearly have one copy that takes place when you put the string into
the vector. From there it depends: when the vector expands, it can copy
construct all the strings into the newly expanded area, then destroy the
old ones -- which (as you suggest) would result in a (relatively slow
deep copy of each of the existing strings -- not to mention temporarily
using a lot of extra memory.
For nearly anything that uses remote ownership (i.e. anything with a
difference between shallow and deep copy), however, that's not usually
the best way. Instead, you can create your new, expanded memory full of
empty items (strings in this case), and then use swap to put the real
ones into the new memory and the empty ones into the old memory, without
copying the actual data.
Of course, on a platform where it get away with it (i.e. most) the
library can just do a shallow copy from the old space to the new, and be
done with it. It's not portable, but the library doesn't need to be
portable internally -- it just has to provide a portable interface. This
is the sort of thing for which template specialization was invented...