Thread: Circular template reference no longer compiles (g++)

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    4

    Circular template reference no longer compiles (g++)

    Hi,
    The following compiles on g++ version 3.2.3 on Red Hat and HP-UX, but fails on 3.4.4 (cygming special). Since that appears to be newer I'm assuming it's my code that's wrong.

    I've cut it down to this example

    Code:
    #include <vector>
    #include <iterator>
    #include <memory>
    
    template <typename T1> class Foo;
    
    template<typename T1>
    class FooItr
    {
    public:
       typedef std::auto_ptr< FooItr<T1> > Ptr;
    
    public:
       FooItr<T1>(Foo<T1>* pFoo) :
          m_itr(pFoo->m_list.begin()) { }
    
       virtual ~FooItr() { }
    
    protected:
       typename Foo<T1>::FooList::const_iterator m_itr;
    };
    
    
    template<typename T1>
    class Foo
    {
    public:
       virtual typename FooItr<T1>::Ptr getItr()
       {
           return FooItr<T1>::Ptr(new FooItr<T1>(this));
       }
    protected:
       friend class FooItr<T1>;
       typedef std::vector<T1> FooList;
       FooList m_list;
    };
    
    int main()
    {
       Foo<int>* p = new Foo<int>();
       delete p;
       return 0;
    }
    The error I get is
    Code:
    t.C: In instantiation of `FooItr<int>':
    t.C:29:   instantiated from `Foo<int>'
    t.C:42:   instantiated from here
    t.C:20: error: no type named `FooList' in `class Foo<int>'
    If I remove the use of FooItr::Ptr from Foo it compiles, so I assume it's circular dependency of FooItr using Foo::FooList and Foo using FooItr::Ptr that's the problem.

    EDIT: Sorry should have been more clear. I realise I can solve this with a "typedef template" (not sure of the proper term) i.e. FooItrPtr<T1>::Type instead of FooItr<T1>::Ptr, but I'm interested in what I'm doing wrong.

    Thanks,

    Stuart.
    Last edited by stumcd; 09-23-2009 at 04:54 PM. Reason: More info

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Yeah, the problem is that FooItr is using Foo::FooList, but that type has not been declared. It is declared in the Foo class, but FooItr has no visibility of this.

    Usually, the best way to do this type of design is to declare the iterator as an inner class of Foo.
    bit∙hub [bit-huhb] n. A source and destination for information.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reference Counting
    By Dae in forum C++ Programming
    Replies: 10
    Last Post: 08-13-2009, 07:34 AM
  2. Using Vectors. MinGW warning
    By Viewer in forum C++ Programming
    Replies: 9
    Last Post: 03-26-2009, 03:15 PM
  3. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM
  4. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM