Jim Lear wrote:
The map iterators are really what tripped me up as an STL newbie. One must understand the iterators are implemented as pairs for maps, and pointers for vectors and other things. By providing an "T operator[](iterator)" function for random access and associative containers (and for sequences maybe), one could achieve a consistant interface.
Container-independent code is an impossible and pointless goal. maps have different semantics from other containers. You may want to iterate over just the mapped values, but other people may want to iterate over the keys, or over the pairs (and indeed, so may you, in other part of your program). Who's to say which of these is right? What you can do is to write iterator-independent code, then use an iterator adapter to convert the iterators over pairs into iterators over the mapped values: #include "boost/bind.hpp" #include "boost/iterator/transform_iterator.hpp" ... my_map_type map; generic_function_on_iterators( boost::make_transform_iterator( map.begin(), boost::bind(&my_map_type::second, _1), boost::make_transform_iterator( map.end(), boost::bind(&my_map_type::second, _1)); (Unfortunately the return type of boost::bind is unspecified.) It would perhaps be useful for map to have member functions like keys_begin(), keys_end(), etc. <snip>
#include <map> #include <string> #include <iostream>
void main() {
Should return int.
typedef map
si_map_t; typedef map ssi_map_t; ssi_map_t table; table["0"]["0"]=20; table["0"]["1"]=21; table["1"]["0"]=10; table["1"]["1"]=11; for (ssi_map_t::iterator i=table.begin(); i!=table.end(); i++) for (si_map_t::iterator j=i->second.begin(); j!=i->second.end(); j++) cout << j->second << endl; // Blech! :-) This is quite obscure for newbies.
<snip> I realise that pairs don't have very helpful member names, but I really don't think it's that weird for iteration to yield both keys and mapped values. Ben.