As you are probably aware, game developers have mixed feelings about STL. Sure, it has advantages, it’s already there, doesn’t have to be coded from scratch, it’s standard. On the other hand, the guidelines are very broad, implementations can vary wildly. Performance/memory guarantees seems to be hard to enforce. Even if the interface is always the same, there’s enough wiggle room underneath to seriously break some applications. Take clear() method for example. All it guarantees is that size() == 0 afterwards. It doesn’t say anything about memory. I’ve heard of at least one STL implementation that would free container memory in clear().
Paradoxically, in many cases it’s easier to get unified, standard behavior if using own STL version (or portable implementation with known characteristics like STLPort). When creating your own container/algorithm library, you have a choice of dropping STL compatibility completely and use your own system or trying to basically build your own, custom version of STL. That’s what EASTL or RDESTL do. This means it’s relatively painless to convert between STL/your library. The problem is, STL interface is not flawless either. The whole allocator model is quite weird, people have been proposing alternatives to iterators, etc.
When experimenting with RDESTL I was mostly concerned with performance and one of the things that’s frustrating┬á is that in some areas I am limited by the way STL has been designed. Consider map/hash_map insert method. Signature looks like this:
typedef pair value_type; pair insert(const value_type& x);
Now, imagine having a hash_map with key that’s expensive to copy. std::string is good example, because people like to use it in all kinds of performance comparisons… You probably do not want to do this in real application, and definitelly not in game, but hey, it’s supposed to be a library for everyone, right? Now, let’s see what happens if we want to insert a new element:
Looks innocent enough. Problem is, it’ll copy the string at least twice! First, when creating temporary object of value_type, then again when copying it to map node. One copy could be easily avoided if only insert signature looked like:
pair insert(const Key& key, const T& value); ... mymap.insert(mystring, myvalue);
Now, STL being so universal library, there’s usually rationale behind design decisions, I’m guessing there’s one here too, but I’m not seeing it. I’m not even trying to say STL should change, rather that if you want to really benefit from writing your own version, it’s sometimes worth deviating a little bit more and not sticking to standard interfaces.