Is it actually guaranteed anywhere that the following reduce-capacity trick will “work”?
int main() {
std::string s = "lololololol";
s = ""; // capacity still non-zero
string(s).swap(s); // ?
}
It doesn’t seem to “work” for me (in that the capacity remains non-zero), and I can’t find anything in the standard that says anything more than that the “contents” must be swapped between the two [here, identical] objects.
Similarly, for sequence containers:
int main() {
vector<int> v { 1,2,3,4,5 };
v.clear(); // capacity still non-zero
vector<int>(v).swap(v); // ?
}
As far as I’m aware, this “trick” is semi-widely used; perhaps this widespread adoption is misguided?
(Of course, in C++11 we have shrink_to_fit [albeit non-binding] instead, making this kind of moot.)
I’ve always been taught that there is no guaranteed standard way to lower the capacity. All methods have been (and still are) implementation defined.
§ 23.2.1\8 says:
This guarantees that the internal pointers of vectors must be swapped.
However, I cannot find anything that guarantee on the capacity of a newly created vector.
§ 21.4.2\1 says that one of the
basic_stringdefault constructor’s post conditions is thatcapacity()returns an unspecified value.§ 21.4.2\3 says that one of the basic_string copy constructor’s post conditions is that
capacity()returns a value at least as big assize().§ 21.4.6.8\2 says that
string::swapruns in constant time, which (effectively) requires that the internal pointers are swapped.As far as I can tell, a conforming implementation could have
string::max_size() { return 4;}, and swapping all internals from one buffer to another would therefore be constant time. (vector can’t do that though)Obviously, take this all with a grain of salt. I’m quoting from the C++ draft from Feb28,’11, and I can’t find specifications for the vector’s copy constructor. Also, not finding evidence for is not the same as finding evidence against.