Thread: iterators

  1. #1
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198

    iterators

    I'm trying to get this one routine to work for my homework, but I just don't understand why this doesn't even compile:
    Code:
    template <typename T>
    void insertOrder(list<T>& orderedList, const T& item)
    {
       // curr starts at first list element, stop marks end
       list<T>::iterator curr = orderedList.begin(),
                         stop = orderedList.end();
    
       // find the insertion point, which may be at end of list
       while ((curr != stop) && (*curr < item))
          curr++;
    
       // do the insertion using insert()
       orderedList.insert(curr, item);
    }
    the error says it expected a semicolon before "curr"
    "What are all you parallelograms doing here?" - Peter Griffin (to Joe and his wheelchair buddies)

  2. #2
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Try:

    typename list<T>::iterator curr

  3. #3
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198
    thanks, that worked, but why? should i study templates? or typenames?
    "What are all you parallelograms doing here?" - Peter Griffin (to Joe and his wheelchair buddies)

  4. #4
    User
    Join Date
    Jan 2006
    Location
    Canada
    Posts
    499
    I learned about templates, but I've never had the need for them yet.

  5. #5
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    thanks, that worked, but why? should i study templates? or typenames?
    It's probably more helpful to revisit static members of a class, i.e. members of a class that exist before any objects are created. Here is a simple example:
    Code:
    #include <iostream>
    using namespace std;
    
    class Demo
    {
    public:
    	static int num;
    
    };
    
    int Demo::num = 10;
    
    
    int main()
    {
    	int result = Demo::num; //No objects exist, using class name
    	cout<<result<<endl;
    
    	return 0;
    }
    Note that these two terms have the same format:
    Code:
    int result = Demo::num;
    
    list<T>::iterator curr;
    list<> is a class just like Demo is a class. So, in your code it looks like you could be calling a static member of the class list<> named 'iterator'. However, there is no static member in list<> called 'iterator'. It's true it doesn't make any sense in the context you used list<T>::iterator for the compiler to interpret that to mean you are calling for the value of the static member named 'iterator'. For instance if there were a static member of list<> called 'iterator', and it equaled 10, the line:

    list<T>::iterator curr;

    would be equivalent to:

    10 curr

    which doesn't make any sense. Nevertheless, the compiler can't sort that out, so it gives you an error.

    There is a type in list<> called 'iterator', which is actually defined in a typedef statement, and it is a typedef for another type. So, in order to tell the compiler that you are NOT trying to call a static data member of list<> named 'iterator', but instead you are trying to declare a variable that is the same type as the type 'iterator' defined in list<>, you have to precede the code with the 'typename' keyword.
    Last edited by 7stud; 03-12-2006 at 06:38 PM.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The reason adding typename fixed the problems is a combination of how templates work and how the C++ grammar is parsed: you are declaring a variable that is of a type that depends on the template parameters. The problem is that the parser is required to initially interpret list<T>::iterator as a generic name of something that depends on the type T. To really work out what list<T>::iterator is, it needs to know what type T is. But, at the point when parsing the template code, no information is available on what type T is (that information only comes in later code, for example, you call the insertOrder() function for a list<int>). The compiler therefore interprets the template code as if list<T>::iterator is a placeholder for a generic name rather than a type, and gets in trouble later on when instantiating the template (i.e. when list<int>::iterator actually turns out to be a type). The typename keyword gives the compiler a hint that, although it doesn't yet have information on what list<T>::iterator is, it will actually be a type when the template is eventually instantiated. This makes the compilers expectations match the reality when the template is eventually instantiated.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. vector of strings with iterators.
    By Mario F. in forum C++ Programming
    Replies: 6
    Last Post: 05-31-2006, 12:12 PM
  2. Using reverse iterators in algorithms
    By 0rion in forum C++ Programming
    Replies: 1
    Last Post: 02-27-2006, 03:19 AM
  3. Writing Iterators...
    By Geolingo in forum C++ Programming
    Replies: 6
    Last Post: 05-29-2003, 09:31 PM
  4. accessing vector elements: iterators are faster?
    By Captain Penguin in forum C++ Programming
    Replies: 1
    Last Post: 11-28-2002, 02:27 PM
  5. Generic Progpammimg Iterators
    By rip1968 in forum C++ Programming
    Replies: 7
    Last Post: 08-06-2002, 10:20 AM