2

In C++03, clear() on a vector is defined in terms of erase(begin(),end()), exactly the same as resize(0), which implies that the capacity stays untouched.

While in C++11, clear() is not defined in this way. Instead, it says the following:

Destroys all elements in a. Invalidates all references, pointers, and iterators referring to the elements of a and may invalidate the past-the-end iterator.

Does it mean in C++11 an implementation is allowed to deallocate and change the capacity of a vector upon a call to clear()? Can we expect v.clear() to have the same effect as vector<T>{}.swap(v)?

PS: Another question of mine also related to vector storage: What happens to the underlying storage upon vector's copy/move assignment?
Any input is highly appreciated on that one too.

Community
  • 1
  • 1
goodbyeera
  • 3,169
  • 2
  • 18
  • 39
  • one question at a time. – Karoly Horvath Mar 08 '14 at 09:39
  • @KarolyHorvath: Yes. But I'm not even sure about the "`allowed`" part. So I'm asking it here :-) – goodbyeera Mar 08 '14 at 09:40
  • @BoBTFish: If that is true, then why the standard changes `clear()`'s definition? – goodbyeera Mar 08 '14 at 09:42
  • i'm just saying it surely doesn't help if your interpretation is inconsistent. whether you're right or wrong is another matter. – Karoly Horvath Mar 08 '14 at 09:43
  • 1
    Note the general rule when reading the standard, functions don't have side-effects other than their defined behavior (unless some aspect is explicitly implementation-defined or unspecified). So for example, `clear()` does not change the capacity, does not replace the vector's allocator with a different one, and does not find all global non-const `int` variables and set them to `23` ;-) – Steve Jessop Mar 08 '14 at 10:17
  • @SteveJessop What, do you mean it can find all global `const int` variables and set them to 23? :) –  Mar 08 '14 at 10:19
  • @hvd: Thanks for the redirection. As one of the comments there says: "`Of course clear() isn't an insertion; but insertions after clear() are still subject to the guarantee, so clear() can't reduce the capacity.`", if that is the case, does it mean that even copy/move assignment cannot reduce capacity (which I will be very surprised at)? – goodbyeera Mar 08 '14 at 10:20
  • @goodbyeera: indeed, you'd expect move assignment to reduce the capacity of the target in the case where the source has less capacity than the target, and quite possibly copy too. I don't think `vector` has any special behavior defined for `operator=` (I can't find it in the standard). So while it's implied that the capacity will change by what the container `operator=` says about allocators and allocated memory, you can probably read this as conflicting with the capacity guarantee. Might arguably be a flaw in the standard? – Steve Jessop Mar 08 '14 at 10:38
  • @goodbyeera I've searched fairly extensively, but I cannot find any permission for move assignment allowing reduction of capacity either. –  Mar 08 '14 at 10:54
  • @hvd: I can't either, but I still doubt the validity of the justification of that answer. The standard says reallocation won't happen `"until the time when an insertion would make the size of the vector greater than the value of capacity()."`. Yes, the `insertion` could very well be after a `clear()`, but at that time, the `capacity()` has already changed, so a reallocation doesn't break the guarantee. (C++11 differs from C++03 in that the guarantee for non-reallocation upon insertion is against `capacity()`, rather than the argument passed in the most recent call to `reserve()`.) – goodbyeera Mar 08 '14 at 11:06
  • @goodbyeera Yes, the standard does have to account for the fact that `capacity()` may change, otherwise there would be no way at all to lower the capacity. However, as Steve Jessop pointed out in a comment here, if a function does not have a described effect of explicitly or implicitly changing the capacity, it is not allowed to change the capacity, because that would be an observable difference from the effect required by the standard. –  Mar 08 '14 at 12:18
  • @hvd: Just found in BS's C++PL 4th, p196, he regards `v.clear();` and `v={};` as something equivalent to `swap(v,vector{});`, though he also regards `s.shrink_to_fit();` equivalent to `swap(s,string(s));` in the same example. However, though not mandatory, `shrink_to_fit()` is allowed to reduce capacity, so it's fair to say that BS implies `clear()` and `move-assign` is allowed to reduce capacity too, otherwise that example will lose its whole point. – goodbyeera Mar 08 '14 at 13:41

0 Answers0