   [C++] Template iterator container issue
  I am trying to create a vector of multiset iterators. The multiset contains template classes. GCC 4.x is not liking this. Here is an example:template <class T>struct SomeStruct {    T id ;};template <class T>class SomeClass {   vector< multiset< SomeStruct<T> >::iterator > test ;};If I replace the T in SomeStruct to int it will compile fine. Here are the errors GCC generates:error: type/value mismatch at argument 1 in template parameter list for 'template<class _Tp, class _Alloc> class std::vector'error:   expected a type, got 'std::multiset<SomeStruct<T>,std::less<SomeStruct<T> >,std::allocator<SomeStruct<T> > >::iterator'error: template argument 2 is invalidAny ideas how to accomplish this?Thanks   
  Did you try vector< typename multiset< SomeStruct<T> >::iterator > test ;   ;  From now on when in doubt 'typename'. I know when to use it when it is clearly obvious there could be confusion. I just did not see the confusion here.Thanks...   ;  The expressionmultiset< SomeStruct<T> >::iteratordepends on a template parameter.Therefore the compiler cannot automatically deduce this expression is actually a type.That is why you have to use typename. It's not about doubting or not.   ;  It also helps when writing debugable template code that you do one thing per line.    vector< multiset< SomeStruct<T> >::iterator > test ;that is more than 1 thing per line.This is one thing per line:typedef SomeStruct<T> TStruct;typedef multiset< TStruct >::iterator Titerator;typedef vector< Titerator > Tit_vector;Tit_vector test;Note that the above fails to compile, just as the original failed to compile.The difference is that the failure to compile happens on a line where you did one thing -- the typedef multiset< TStruct >::iterator line.  So you know what line went wrong.;  Storing iterators is usually a bad idea. What are you really trying to accomplish?   ;  It's not a bad idea at all, no. That's a nice way to add an index to the data.   ;Quote:Original post by loufoqueIt's not a bad idea at all, no. That's a nice way to add an index to the data.Storing iterators is not wise. There are many situations in which iterators can become invalid, and if you do anything nontrivial with a container, chances are you will encounter invalidated iterators and the associated problems.If your data is static enough that you don't have to worry about iterator invalidation, you still shouldn't need to store iterators; chances are if you want to do this you're misusing your chosen container, and there is a cleaner way to get fast indexing.   ;Quote:Original post by ApochPiQStoring iterators is not wise. There are many situations in which iterators can become invalid, and if you do anything nontrivial with a container, chances are you will encounter invalidated iterators and the associated problems.=There are situations in which iterators can become invalid, but they're all well-known and well-documented. Moreover, the situations where you can't just use a real index (that is, anything other than vector or deque) are exactly the situations where unexpected iterator invalidation is rare. If you have a better way of letting an object erase itself from a std::list in O(1) time, I'm all ears.   ;  I got burned pretty badly storing std::map iterators as members of a class, when they pointed to a map that was their sibling in the class. When the object was default-copied, the map would be copied, but the iterators still pointed to the copy-ee, which by the time they were dereferenced was often out of scope. I didn't think through the situation enough to realize that I needed a non-default copy constructor and operator=, or, once I did realize this, what exactly it should do.It was made more complicated by the fact that some of the iterators could be end iterators, to represent non-existent values. It works fine now, but you have to be careful. I had to copy/assign the map, then manually re-find and reset the iterators, taking into account the possibility of end iterators. That was a nasty two days of debugging.   