Monday, March 12, 2012

The Beauty of Vectors

After months of only using arrays in C++, I have recently started using vectors as my go-to basic data structure. While arrays are great for lower level code and tasks that require the highest level of efficiency, in most cases vectors will prove to handle things in a much simpler and more elegant way. I personally like that vectors provide the user with a way to retrieve the size of the vector. It is no longer needed to keep track of the size of an array with a separate variable, which can really make vectors easier to work with.

Often times when using simple arrays it can be a nuisance to deal with managing the objects they hold. Vectors also work magically with memory. When vectors go out of scope, it calls the destructor on the elements it holds. I would argue that using a smarter container like vector instead of an array decreases development time because it helps reduce programming errors.

One of the interesting caveats involved with using vectors is the way iterating is handled. At first glance, it can be easy to assume that a simple for loop from int i = 0 to some_vector.size() would work just fine.

for (int i = 0; i < someVector.size(); ++i)
    cout << someVector[i] << " ";

Well, it does, but the field that holds the size in vector is unsigned, so a type warning occurs at compile time, and that means there is probably a better way to do it. The first, simple fix, is to simply change the type of 'i' in the loop to an unsigned type so that the comparison i < someVector.size() will not result in a warning. Unsigned int will do, but it turns out vector actually uses the size_t type for this purpose, and that ends up being a far more correct solution than simply using an unsigned specified type.

for (size_t i = 0; i < someVector.size(); ++i)
    cout << someVector[i] << " ";

We can still do better by using iterators instead of using the standard for loop. Vectors have both a begin() method and an end() method that both return iterators. (Obviously begin returns an iterator to the beginning of the vector and end returns an iterator to the end). Hell, we could even use rbegin and rend which return reverse iterators. Here is the simplest way to use them in one for loop:

for (vector<T>::iterator it = someVector.begin(); it != someVector.end(); ++i)
    cout << *it << " ";

Notice that in this case we had to dereference the iterator object since it is simply pointing to the consecutive elements in someVector.

Anyways, vectors are proving themselves to be a very, very cool alternative to arrays. When using them just be careful that you initialize them properly if the initial size is known. Check them out! http://www.cplusplus.com/reference/stl/vector/

No comments:

Post a Comment