I try to hide the underlying implementations of my containers as much as possible.
So in your example, I would start by using a typedef instead of referring directly to the vector (later you will see why):
typedef std::vector<string> MyStringCollection;
Then, I try to use constructions that rely as little as possible on the underlying implementation. In this case, I want to iterate over the container and use the values in the container, like this:
for(MyStringCollection::iterator it=mycollection.begin(); it!=mycollection.end(); ++it)
{
// use *it
}
With the typedef the users of your collection only have to use MyStringCollection::iterator without needing to know what MyStringCollection actually is.
Note that in C++0x, you could use auto, which is even shorter (making my argument for the typedef less relevant).
The advantage of this is that now becomes quite easy to change MyStringCollection from std::vector to std::list. If because of performance reasons you decide that a list would be better suited, you only have to:
- Change the typedef from std::vector to std::list
- Have a quick look to all the places where MyStringCollection is being used (which will be easier to find than looking up all uses of std::vector