views:

280

answers:

3

Yet again I find myself struggling with the C++ syntax.

I'm trying to iterate over a list of generic objects. That is I have objects of a class Event<Q>, crammed into a std::list<Event<Q> >.

So I'm trying to get an iterator over the list and intuitively thought that

std::list<Event<Q> >::iterator it;
for (it = events.begin(); it != events.end(); it++) { ... }

should solve the problem. However, i keep getting these errors:

..\calendar.h:48: error: expected `;' before "it"
..\calendar.h:49: error: `it' was not declared in this scope

Is there a reason for it being this difficult?

+6  A: 

Sure this should work, but it sounds like you either have one or both of the following in action.

  • Have Q a template parameter or a type that somehow otherwise depend on it (typedef to it). Put a typename before std::list then, so that the compiler knows that ::iterator is a type and can proceed analysis properly (it could be a static value member). Knowing it is a type, the compiler can produce better diagnostics for template definitions, and you are required to tell whether it is a type using typename.
  • Have events a const list. Use const_iterator then.

Update: The shown compile error surely indicates that the first point is true: Q directly or indirectly depends on a template parameter, and you have to put typename like so:

typename std::list< Event<Q> >::iterator it;

The compiler believes you that it is a non-type, and so it requires some operator or semicolon behind ::iterator (like, a multiplication). Put typename to make it know it names a type instead.

Update: See the Template FAQ for similar template issues and solutions.

Johannes Schaub - litb
Thanks a lot, that solved it. I did:`typename std::list<Event<S > >::iterator it`and it magically worked
Nubsis
Oops I missed the Event<> part around Q xD Glad it works :)
Johannes Schaub - litb
Your explanation was very lucid and also solved my problem :) Thanks a lot, Johannes!
Adrian Petrescu
A: 

in your sample , what is S ?

list<Event<S> >::iterator it; // what is S 
for (it = events.begin(); it != events.end(); it++) { ... }

can you try putting a native type there ?

list<Event<int> >::iterator it; 
for (it = events.begin(); it != events.end(); it++) { ... }

or simplify it even more ?

list<int>::iterator it; 
for (it = events.begin(); it != events.end(); it++) { ... }
Andrew Keith
A: 

Have you got the std namespace imported? Should the iterator declaration have been:

std::list<Event<S> >::iterator it;
MHarris