Saturday, May 12, 2007

STL Fuckup


Today I have two things to say:

First beware of SGI's Standard Template Library Programmer's Guide. Although it is the STL docu out there it is not standard compliant!

For example it claims there is a vector(size_type n) and a vector(size_type n, const T& t) constructor for the vector class. This is not true. Section 23.2.4 of the ISO-C++ standard defines explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());.

You could argue that they just split the two cases into to different constructors. But apart from the missing default value for the second argument and the completely missing third argument this is not true. SGI explains:
  • vector(size_type n): Creates a vector with n elements.
  • vector(size_type n, const T& t): Creates a vector with n copies of t.
For me this means that the first constructor creates n objects by using the default construtor of the particular type. Especially because the documentation on Sequences, which is a model of vector, calls it a "Default fill constructor". In contrast to the first constructor the second one fills the vector by copying the given object.
And this leads to today's second point: there is no constructor to let the vector be filled with n objects each constructed by the default constructor. Instead the objects in the vector are always copies of the given one - which is discarded afterwards, by the way. This is a problem as soon as it matters, whether the objects are copied or not.

For instance imagine some struct Foo with a smart pointer of some type Bar being a member. The Foo constructor creates a new Bar object with operator new and passes the pointer to the smart pointer's constructor. What you want if you arrange such Foo objects within a vector normaly are n different Foo objects. But what you get are n Foo objects whose smart pointers all encapsulate the same Bar object. This is because the Foo constructor runs only once. The rest is done by the copy constructor.

I see no efficient way to get the vectory filled with n independent Foo objects. The best way I can see is like this:

vector<Foo> v;
v.reserve(n);
for (unsigend i=0; i<n; i++) {
    v.push_back(Foo());
}

Anyone a better idea? If yes send me an email. I'm eager to knonw whether I miss something.

No comments:

Post a Comment