views:

112

answers:

2

When I try to compile this:

#include <map>
#include <string>

template <class T>
class ZUniquePool
{               
        typedef std::map< int, T* > ZObjectMap;
        ZObjectMap      m_objects;
public:
    T * Get( int id )
    {
        ZObjectMap::const_iterator it = m_objects.find( id );
        if( it == m_objects.end() )
        {
            T * p = new T;
            m_objects[ id ] = p;
            return p;
        }
        return m_objects[ id ];
    }
};

int main( int argc, char * args )
{
    ZUniquePool< std::string > pool;
    return 0;
}

I get this:

main.cpp: In member function ‘T* ZUniquePool<T>::Get(int)’:
main.cpp:12: error: expected `;' before ‘it’
main.cpp:13: error: ‘it’ was not declared in this scope

I'm using GCC 4.2.1 on Mac OS X. It works in VS2008.

I'm wondering whether it might be a variation of this problem: http://stackoverflow.com/questions/1364837/why-doesnt-this-c-template-code-compile But as my error output is only partially similar, and my code works in VS2008, I am not sure.

Can anyone shed some light on what I am doing wrong?

+6  A: 

You need typename:

typename ZObjectMap::const_iterator it = m_objects.find( id )

Since the type of ZObjectMap is dependent on the template parameter, the compiler has no clue what ZObjectMap::const_iterator is (it could be a member variable). You need to use typename to inform the compiler to assume it will be some sort of type.

R Samuel Klatchko
Fantastic! Not only did you solve my problem, but you also made me realize something fundamentally important about the way templates are treated by the compiler.Thanks a bunch.
Setien
+2  A: 

Also to mention, GCC 4.5.0 gives the following output which would help you to solve the problem:

main.cpp: In member function 'T* ZUniquePool<T>::Get(int)':
main.cpp:12:7: error: need 'typename' before 'ZUniquePool<T>::ZObjectMap:: const_iterator' because 'ZUniquePool<T>::ZObjectMap' is a dependent scope
main.cpp:12:34: error: expected ';' before 'it'
main.cpp:13:11: error: 'it' was not declared in this scope
main.cpp: At global scope:
main.cpp:23:5: warning: second argument of 'int main(int, char*)' should be 'char **'
Kotti
Thanks - I'll keep that in mind for future template compile errors (switching to newer versions of GCC that is).
Setien