I'd like to create a std::map
that contains a std::vector
of iterators into itself, to implement a simple adjacency list-based graph structure.
However, the type declaration has me stumped: it would seem you need the entire map type definition to get the iterator type of said map, like so:
map< int, Something >::iterator MyMap_it; // what should Something be?
map< int, vector<MyMap_it> > MyMap_t;
Is there some sort of partial map iterator type I can get with just the key type, so I can declare the full map?
You could use forward declaration of a new type.
With this indirection the compiler should let you get away with it. It is not so very pretty but honestly I don't think you can break the self referencing easily.
I didn't like deriving from a container in my previous answer so here's an alternative:
Now you have to use
rec_map_gen<int>::t
,rec_map_gen<int>::t::iterator
, etc, but you also have access to allstd::map
's constructors. It's too bad C++ doesn't allow typedefs to be templated.Using a derived iterator type should be OK. You can still initialize a reverse iterator from an element of this structure, for example.
Not too ugly, considering…
This works in GCC 4.0.1 and compiles fine in Comeau strict mode.
The template definitions are parsed and deferred until they're instantiated. The compiler doesn't even see what a rec_map_iterator is until it's time to create one, by which time it knows how to do so ;v) .
Here's the test program I used.
In addition to Potatoswatter's answer, if you don't mind having to refer to the entire templated map type multiple times, you only need to subclass the iterator and don't need any pre-declarations:
Then use the full type:
Also, here's an update (my favorite so far) for C++11 by declaring rec_map as an alias, which can be templated:
This works the same as Potatoswatter's version: