I think it would be very enlightening for students and professionals-just-starting out and needing to make decisions such as whether or not to use the standard containers in their code to read this thread all the way through. I've done it at points where I've decided to post to ensure I'm keeping up with both the current and past spirit of this thread, and I just did it again and was struck by some observations that I feel the targets I mentioned should also be aware of. Its been pointed out several times by several posters, but...

...particular points of those who advocate not using the standard containers... keep shifting.

There is this shell game being played. Somehow, the topic of particular bugs gets dropped, and yet somehow the debugabillity is still called into question. Design issues are mentioned at several points, yet particulars get clouded over by a fog of "ugly" and "difficult". When particulars do come up, they are responded to quickly, and despite the fact that so far the most of the issues have been ones of understanding how to use the standard containers (not deriving but extending orthogonally), what their guarantees are (algorithmic complexity issues), and the language features they use (templates and namespaces), well...

...there is never an acknowledgement of those issues being resolved.

I don't like flames (much), but souldog's earlier comment about obsolescence keeps bouncing around in my head. I'm not sure how to word this without sounding like I'm attacking someone, but let me try. I have seen similar opposition to using the standard library containers in person. And I have come to believe that much of the opposition is a psychology, a tiredness, a "I don't want to have to learn yet another thing." When I got out of college I was so exhausted with learning that I didn't pick up a technical book for close to 3 months. I know that feeling innately, it is a constant struggle for obsessive people like myself, and I see the exact same symptoms in responses in this thread.

Specifics cases against the standard containers are avoided or incorrect (algorithmic assumption as a case in point) because they are not known, yet.

And the whole point is to keep the task of learning away.

And sometimes a defensiveness creeps in, and there is this explosion of sound and fury, which is supposed to be one of those societal signals to back off and let the issue die out.

And I don't want it to die like that.

I believe that a lot of those who come to codeguru to read the forums want solid answers to the questions they have in their professional life.

I believe that there are actual, scientific metrics on which programming decisions should be made. We don't suggest to a person requesting information on how to make a driver to use Visual Basic. We don't suggest to a project which carries a strong requirement for stability and correctness (life support systems, for example), that the team use a language or language features they are not already intimate in. Sure, some of the metrics can have poor precision, and possibly there might be a problem choosing between several courses of actions do to different suggestions by different metrics. But even that type of case needs to be established, not passed over as an initial assumption.

Some very good metrics I have seen in this thread included component construction and time. Those are great metrics because they are the basis for the industrial revolution. When John Hall built the first rifle factory to use interchangeable parts, the entire point was a realisation of the dreams of Thomas Jefferson and Eli Whitney to get some degree of automation possible in construction to increase production capabilities by decreasing the time for construction of the various phases.

Software design has been undergoing its own industrial revolution. And just as in the physical construction sector, software domains have many concepts of components and various dynamics for connecting and interchanging them.

Look at the evolution of MFC's containers. Originally, they were built in the zeitgeist of object-oriented design. So there were some basic object containers for holding pointers to any class derived from CObject. This allowed for a useful type dynamic where objects of various different concrete types could coexist inside a container and only the algorithmic specification of the container type was exposed. This was the polymorphic method of generic programming. However, it had to be stated outside of the code that such containers were most useful when the actual classes were all derived from a base furthur down the hierarchy, since one often uses such containers in code to loop through a more refined interface, and code could easily litter with casts as one tries to expose the interfaces. Some of that gets cleaned up if you derive from the containers, and MFC even provided some utility derivations for things like their string utility class, but even at this stage you begin to see the coupling involved in acquiring a solution, and the inability for the framework to provide a solution for those who do not desire the CObject interface with its emphasis on application core features like serialisation.

Then we get language support for templates and eventually the MFC engineers start building in support for newer containers that take advantage of the template mechanism. However, to maintain backward support, their core framework is stuck with object relationships built in the object-oriented days. They desire these new containers to have support for the framework built in, so they are placed into the framework hierarchy. And they do not demonstrate some of the newer componentisation techniques made available by templates (I suspect because the engineers were unfamiliar with the techniques), and they also fail to even expose older componentisation techniques like iterators. So they restrict their use cases.

But then you have David Musser and Alex Stepanov working over in Ada on this idea for a generics library. With the help of people like Meng Lee, there was all of this intellectual discussion about library design and abstraction in c++ going on over at HP. With heavy use of the iterator abstraction, factoring out allocation policies, and generic type access, the STL was built concentrating solely on the benefits of abstracting out the ideas of object relationships and algorithms applied to them. These are the fields that complexity theory and combinatorics had already well established a mathematical framework for, and there were widely known efficient algorithms that were useful all over the place. Using templates also had the benefit of allowing the compiler to use the static instantiation to make type-specific optimisations and much of the code necessarily inlined itself due to template visibility issues. The components were clear and customisable. One could add algorithms for entire classes of iterator abstractions. One could root a hierarchy on a container of polymorphic pointers however one desired.

Even though MFC's newer template containers shared some of the benefits that the STL provided, they were still monoliths rooted in a framework hierarchy without an iterator abstraction for generic algorithmics. STL's containers were free objects and algorithms, customisable and transportable. And they're faster, about as fast as a container can get since the modern optimisers use all of the type information available to make specific access calls almost exactly the same as if there were no objects and only naked calls to a free structure (for instance, vector read access is very often found in assembly as a simple pointer add offset and dereference load). In fact, the only suggestions I have ever seen for improving the efficiency of the standard containers and algorithms (which I reiterate are built on mathematical notions well studied for efficiency) has been the proposal for new language semantics for move constructors to keep out the unnecessary copy or two that goes on in the language construction mechanism.

On these metrics, STL happens to have the edge by quite a bit. It is much more useful as transposable components, it is faster both in milliseconds and actual labor-hours for immediate algorithm reuse. And now, these containers are standardised and an integrated part of the legal language we program in. These are all of the metrics that point to the STL being the current leader in this particular niche of the industrial revolution. Other competitors in this field of components, like the Booch c++ Components, also fail the challenge for similar reasons.