[Effective-cpp] Item 1: Uses and Abuses of vector

Balog Pal pasa at lib.hu
Sat Oct 23 09:27:02 EDT 2004


> Understand when you want to use at() verses [].

A good advice, though didn't help me out. :)   Can someone give a real-life
case when using at() is good?  I mean in a production environment.

As i recall my use of containers, I either accessed an element that was
(supposed to be) there, or the access created the possibly missing element
(growing the container).  If the first kind of access failed, it is a bug in
the program.  Guarded by precondition checks and assert-like stuff.  IMHO
there's a general consensus bug detection shall not be handled using
exceptions, and killing the process right there is likely better than
allowing extra mess-up in stack unwinding, until some out_of_range handler
is reached.  Also, what could we do in that handler?

I hope quality inplementations of SL put asserts in debug build of vector's
op[], helping development.

> vector v;
> v.reserve(2)
>
> v[0] = 1;
>
> This assignment might work for certain compilers for a while, but is
> wrong in general since the vector is empty.

'might work' will likely depend on two factors:
- the implementation of op[].  It may just address the element, or check the
bounds before that.
- the element-type of the vector, and what its ctor does.  when a
nonexisting element is addressed it means it was not constructed in that
place.

> o) Be const correct. In particular, use const_iterator when you are not
> modifying the contents of a container. Personally I struggled with the
> idea of const for years.  I think it is just one more helpful tool to
> make life easier and you do it when you can.

I' a big fan of const but for this situation I recall Scott Meyers had
reservations on using const_iterator in ESTL.

> o) Practice reuse:  Prefer reusing existing algorithms, particularly
> standard algorithms (e.g. for_each) instead of crafting your own loops.

Does the book really say that? (Sorry, my copy didn;t arrive yet, so I use
Gotw#74.)
Gotw says it's 'Season to taste' with good explanation.   And that 'prefer'
applies only to the cases where the resulting code is more clear than a for
loop.

> Reuse might prevent the possibility of introducing more errors like
> prefix forms, != etc.

Those are not so serious errors, If the code compiles you very likely get
the same binary on a good optimizing compiler -- and if it doesn't it is
trivial to fix.  Certainly it is a good to write the suggesed/better code.

However using the algos with the current facilities of C++ mey be not too
productive, and create obscure or even unreadable code.   While a for loop
is easy to read for anyone I met.   That is sad, as I'd be a big fan of
algos too, but that is the truth.

> I hope I covered the major points.

GotW also has a point on 'Avoid needless recalculations', specially calling
end() in the loop condition.

my old-stype idiomatic iteration loop is like this:

for(int i = 0, maxI = arr.GetSize(); i < maxI; ++i)

with vector it would look like

for(vector<int>::iterator i = vec.begin(), endI = vec.end(); i != endI; ++i)

{I'd use a const with maxI, but the language does not allow that.}

That form shall express 'element count will not change' during the
iteration, while testing end() in the condition means it can change.









More information about the Effective-cpp mailing list