2

I am just trying to declare a map iterator but I get a compile error saying "expected ; before it"

I believe it is because I haven't included the whole std namespace (using namespace std;) but I intentionally dont want to include all of it.

My code:

#include <map>
#include <string>

template <class Object>
class Cont
{
    public:
       Cont() {}
       Object* get( unsigned int nID )
       {
           std::map <unsigned int, Object*>::iterator it = m.begin(); // error here "expected ; before it" what is this error?

           for ( ; it != m.end(); it++ ) 
           {
               if ( (*it).second->ID == nID ) { return (*it).second; }
           }

           return NULL;
       }

       std::map <unsigned int, Object*> m;
};

I have tried this aswell but it doesn't work:

std::map <unsigned int, Object*>::std::iterator it = m.begin();
user593747
  • 1,484
  • 4
  • 32
  • 52
  • Do you forward declare the `Object` class somewhere before this template class? If no, then that may be what is causing it. – Håvard S May 14 '11 at 05:36
  • Lots of detail here: http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-template-and-typename-on-dependent-names/613132#613132 – Steve Jessop May 14 '11 at 10:33

3 Answers3

12

If I'm not mistaken because you are using a template argument you need to prefix the iterator declaration with typename.

typename std::map <unsigned int, Object*>::iterator it = m.begin();
GWW
  • 43,129
  • 11
  • 115
  • 108
  • 3
    I found this [discussion](http://pages.cs.wisc.edu/~driscoll/typename.html) of typename to be helpful in understanding why and when typename keyword is needed. – rlduffy May 14 '11 at 06:56
1

What's your compiler and flag settings? I was able to build this OK.

// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <map>
#include <string>

class Foo
{
public:
    int ID;
};

template <class Object> class Cont
{
    public:
       Cont() {}
       Object* get( unsigned int nID )
       {
           std::map <unsigned int, Object*>::iterator it = m.begin(); // error here "expected ; before it" what is this error?

           for ( ; it != m.end(); it++ ) 
           {
               if ( (*it).second->ID == nID ) { return (*it).second; }
           }

           return NULL;
       }

       std::map <unsigned int, Object*> m;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Cont<Foo> c;
    c.get( 2 );
    return 0;
}
holtavolt
  • 4,378
  • 1
  • 26
  • 40
  • 2
    You are using an MS compiler which **sometimes** can figure it out anyway. According to the standard it should still complain about the missing keyword. – Bo Persson May 14 '11 at 06:14
  • Yeah - I've been bitten by this in the past, but haven't used gcc recently and forgot about it. I confirmed the error and resolution using codepad: http://codepad.org/GSCVOVj1 - There's a also an SO thread explaining that the typename keyword is disambiguating the use of type vs. value here: http://stackoverflow.com/questions/1215055/why-is-the-use-of-typedef-in-this-template-necessary -- most useful take-away I get from this is that this is yet another benefit (aside from readability) of using a typedef for your iterators. – holtavolt May 14 '11 at 14:30
0

You don't say what compiler you're using, but just by cutting and pasting this into a new file, it compiles fine in VS2010. You don't need to using namespace std; certainly....

(And your wrinkle of putting another std:: before iterator was creative, but isn't correct. :-) You're specifying that the map class template is located in namespace std::, and iterator is a type that's nested within the map template.)

jwismar
  • 12,164
  • 3
  • 32
  • 44