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

Timothy C. Wright tim at tcw321.com
Fri Oct 22 21:57:45 EDT 2004


Item 1:  Uses and abuses of vector

The various pitfalls and issues dealing with the vector container are 
discussed.

There are two accessors for the vector container that have slighty 
different meaning.  v[0] gets the zeroeth element of the vector.  If 
there is not any elements in the vector, then we don't know what will 
happen.  The standard allows bounds checking but does not require it for 
this function.  Bounds checking is not required so it can be efficient 
and replace the old array.  The other element accessor, v.at(0), does 
require bounds checking and is guaranteed to throw a std::out_of_range 
exception. Understand when you want to use at() verses [].

The vector has the following functions:

reserve(N)
capacity()

reserve(N) creates a  memory buffer of at least N in size internally for 
the vector object.  It does not create any element objects in that memory.

capacity reports the size of the vector's memory.  Once this memory is 
full,  more objects pushed on the vector will cause it to allocate a 
bigger buffer and move everything into that buffer.  If we have the 
following:

vector v;
v.reserve(2);

then a call to capacity will be guaranteed to return at least 2.

There are differences between these two functions and size and resize.  
The former report about the memory size of the vector independent of the 
number of elements. The latter two report the number of elements 
actually in the container and resize adjusts the number of elements by 
adding or removing them at the end. 

We also should be careful about compiler implementations that might mask 
problems.  For example:

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.  There are no requirements 
in the standard on how the compiler should deal with these errors.

There are some other minor topics which I will list with all the item's 
guidelines.

o) Remember the difference between size/resize and capacity/reserve

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.

o) Prefer comparing iterators with != , not <.  The book mentions that 
this is allowed for all iterators so it is easy to change containers.  
However, as stated in Effective STL, it might be more complicated than 
just != to switch containers in the code and it might be too costly to 
keep that avenue open.  But != is a easy price to pay, it works for 
everyone.

o)  Get in the habit of using the prefix forms of -- and ++ by default, 
unless you really need the old value.

o) Practice reuse:  Prefer reusing existing algorithms, particularly 
standard algorithms (e.g. for_each) instead of crafting your own loops.  
Reuse might prevent the possibility of introducing more errors like 
prefix forms, != etc.

I hope I covered the major points.

Regards

Tim








More information about the Effective-cpp mailing list