[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