C++ is full of wicked little surprises. Here’s one surprise that I learned about not too long ago.
In C++, the order of destruction is very carefully defined. Objects are "destroyed in the reverse order of the completion of their constructor." (C++ Standard sections 3.6.3 and 6.6.2). For arrays, elements are "destroyed in order of decreasing address (that is, in the reverse order of the completion of their constructor)" (22.214.171.124). Even temporary objects have well-defined destruction semantics: they are "destroyed in reverse order of the completion of their construction." (12.2.4)
So it comes as a wicked little surprise that elements in STL containers do not have a well-defined order of destruction. Consider:
std::vector<Obj> v;v.push_back( Obj(1) );v.push_back( Obj(2) );v.push_back( Obj(3) );
It’s natural to assume that for any conforming C++ implementation, the order in which the elements of v are disposed when v goes out of scope is always ~Obj(3), ~Obj(2), then ~Obj(1). In other words, based on our knowledge of how C++ works, we would assume that elements are cleaned up in reverse order of their insertion. However, the C++ Standard makes no such promise. All it says (23.1.5) is that when a container is destroyed, the "destructor is applied to every element of [the container]; all the memory is deallocated." Thus, the objects could be destroyed in the order 3,2,1 or 1,2,3 or even 2,1,3. Implementors have the flexibility to define the order of destruction for elements in whatever way provides the best performance.
The moral of the story: don’t depend on the order of destruction of elements in STL containers. If you need an absolute guarantee, use an array.
P.S. You probably have a strange urge to know the order your current STL implementation chooses. My recommendation: don’t bother. The order could just as easily change in the next release, or when you port your project to another platform. You’re better off assuming the order is completely random. Wicked, but true.