A common pattern with STL containers is this:
map map;
for(map::iterator iter = map.begin(); iter != map.end(); ++iter)
{
.
Not sure what you mean by "overhead". If it simplifies the way you write your code, use it, otherwise stick with the longhand.
If it's only used in a restricted scope, put the typedef in that same scope. Then it doesn't need to be published, or documented, or appear on any UML diagrams. For example (and I don't claim this is the best code ever in other respects):
int totalSize() {
typedef std::map<Key, Value> DeDuplicator;
DeDuplicator everything;
// Run around the universe finding everything. If we encounter a key
// more than once it's only added once.
// now compute the total
int total = 0;
for(DeDuplicator::iterator i = everything.begin(); i <= everything.end(); ++i) {
total += i->second.size(); // yeah, yeah, overflow. Whatever.
}
return total;
}
Combining with Ferruccio's suggestion (if you're using boost), the loop becomes:
BOOST_FOREACH(DeDuplicator::pair p, everything) {
total += p.second.size();
}
And combining with bk1e's suggestion (if you're using C++0x or have features from it), and assuming that BOOST_FOREACH interacts with auto in the way I think it should based on the fact that it can normally handle implicit casts to compatible types:
std::map<Key, Value> everything;
// snipped code to run around...
int total = 0;
BOOST_FOREACH(auto p, everything) {
total += p.second.size();
}
Not bad.
Over the past few years I've really tried to move away from using manually written loops in preference to using the STL algorithms. Your above code can be changed to:
struct DoLoopBody {
template <typename ValueType>
inline void operator()(ValueType v) const {
// ...
}
};
std::for_each (map.begin(), map.end(), DoLoopBody ());
Unfortunately the class DoLoopBody cannot be a local class, which is often highlighted as a disadvantage. However, I see this as an advantage in that the body of the loop can now be unit tested in isolation.
You can use Boost.Foreach
Personally I think MYMAP::iterator is more readable than map<int,string>::iterator or even std::map<int, std::string>::iterator so I always do the typedef. The only overhead is one line of code.
Once the code is compiled, there will be no difference in the size or speed of the executable. It's just about readability.
A future version of the C++ standard (known as C++0x) will introduce a new use for the auto keyword, allowing you to write something like the following:
map<Key, Value> map;
for(auto iter = map.begin(); iter != map.end(); ++iter)
{
...
}
If the typedef is local to a single function it doesn't even need to be a nice name. Use X or MAP, just like in a template.