Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
187 views
in Technique[技术] by (71.8m points)

c++ - Can we rely on the reduce-capacity trick?

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.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.18 says:

The expression a.swap(b), for containers a and b of a standard container type other than array, shall exchange the values of a and b without invoking any move, copy, or swap operations on the individual container elements...

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.21 says that one of the basic_string default constructor's post conditions is that capacity() returns an unspecified value.
§ 21.4.23 says that one of the basic_string copy constructor's post conditions is that capacity() returns a value at least as big as size().
§ 21.4.6.82 says that string::swap runs 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...