1

I was wondering what happens with the capacity of a container like a vector or a string when you copy it. I ran the following experiment (Clang 8) not knowing exactly what to expect.

#include <iostream>
#include <vector>
#include <string>

int main()
{
    using namespace std;
    vector<int> v;
    v.reserve(100);
    vector<int> v2 = v;
    cout << v2.capacity() << endl;
    // 0
    string s;
    s.reserve(100);
    string s2 = s;
    cout << s2.capacity() << endl;
    // 15
    return 0;
}

So it looks like capacity is not copied. That seems reasonable on the one hand, because it would be wasteful to make the copies take more memory than necessary. But, on the other hand, I might have expected the copies to have the same capacity. Maybe I did want to make several vectors with some preallocated capacity. More generally, I usually expect copies to behave similarly to the copied object, put coarsely, to return the same results when const methods are called. I know there is no such rule and there are surely many cases in the standard where this does not happen. But in any case, I would like to know if there are any specifications about it, if the standard explicitly says that the capacity of a container does not need to be maintained across copies. Ideally, I would like to get some specific behavior, e.g. assuming that what clang does is correct (not maintaining the capacity), then I would like to take for granted that capacity is never going to be maintained (e.g. something like "capacity of the copy is what you would get after shrink_to_fit"), although I imagine the standard would leave that up to the compiler.

jdehesa
  • 58,456
  • 7
  • 77
  • 121
  • How would you explain reference-counted objects? There is no copying there also, but "copies" are made. – PaulMcKenzie Jul 11 '19 at 17:30
  • @PaulMcKenzie I don't understand what you mean. In any case, e.g. `shared_ptr` has pretty explicit copy semantics (the shared pointer itself is copied, there is the reference counter, etc), here I'm not sure where it is specified that the capacity should or should not be copied over to the new object. – jdehesa Jul 11 '19 at 17:36

1 Answers1

0

It is implementation defined. According to the c++ 17 Standard (for std::basic_string, 24.3.2.2 basic_string constructors and assignment operators)

capacity() a value at least as large as size()
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Right, but not _any_ value at least as large as `size`. E.g. if you call `reserve`, that conditions the value of `capacity`. In any case, from that description I could expect that a copy would return the same value. – jdehesa Jul 11 '19 at 17:33
  • 1
    @jdehesa I do not understand what you mean by saying "Right, but not any value at least as large as size" capacity and size uses the same type size_type. – Vlad from Moscow Jul 11 '19 at 17:38
  • 1
    @jdehesa capacity is simply not considered to be a part of the value of a container. Two containers are equal if the elements in their range are equal and this doesn't require capacity to be equal (most containers don't have a capacity). You want a vector containing `{1, 2, 3}` to be equal to another vector of the same type containing `{1, 2, 3}` even if one's capacity is greater than the other. – François Andrieux Jul 11 '19 at 17:42