Thread: Declare a template class as a friend?

  1. #1
    Registered User
    Join Date
    May 2003
    Posts
    82

    Declare a template class as a friend?

    I'm feeling really silly as this is just a syntax detail, but I have not managed to find a decent example on the web or in my textbooks.

    How do you define a template class declared outside the class as a friend? I'm working on a linked list container class, and defining my List class as a friend of Iterator, which looks something like this:

    iterator.h
    Code:
    #include "node.h"
    
    template <class T>
    class Iterator
    {
    	// declare class List as a friend somewhere?
    	public:
    		typedef *Node<T> nodePtr;
    
    		T& operator*();
    		bool operator==();
    		//etc
    	private:
    		nodePtr dataNode;
    		void setNext();
    		void setPrev();
    		void getNext();
    		// etc accessors/mutators for node manipulation
    }
    list.h
    Code:
    #include "iterator.h"
    
    template <class T>
    class List
    {
    	public:
    		typedef Iterator<T> iterator;
    
    		void push_back(const T& val);	// functions need access to Iterator's 
    		void push_front(const T& val);	// private methods to change sequence
    		void insert(iterator pos);	// of list.
    	private:
    		iterator head;
    		iterator tail;
    };
    They're may be some syntax errors. I don't have the code in front of me, so I'm just typing this in notepad from memory.

    I looked at the STL list header, and they got around this buy declaring their iterator inside the list function, but I'm not sure thats appropriate for this project. I found plenty of examples on how to declare a non-template class as a friend, and I experimented with possible ways of writing a template version, but my compiler didn't like any of them. In case it effects the template syntax, I'm currenty using MS VC++ 6.0 SP 4.

    Thank you,
    AH_Tze

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Code:
    template <class T>
    class List
    {
        friend class Iterator<T>;
    ...
    };
    gg

  3. #3
    Registered User
    Join Date
    May 2003
    Posts
    82
    Just plugged that into Dev-C++, although I switched the friend, so within Iterator class definition it declares "friend class List<T>".

    Compiles with an "List is not a template" error. After looking at non-template friend examples, I think I need some placeholder code in iterator.h which tells the compiler a class List will be defined, but I'm not sure how to write this for a template class.

    I wrote a quicky test program in which class List tries to access class Iterator's private member function. Hopefully this will illustrate my problem.

    main.cpp
    Code:
    #include "list.h"
    
    int main(int argc, char *argv[])
    {
        List<int> testList;
        int testVal;
        
        testVal = testList.getData();
      
      system("PAUSE");	
      return 0;
    }
    list.h
    Code:
    #ifndef LIST_H
    #define LIST_H
    
    #include "iterator.h"
    
    template <class T>
    class List
    {
      
        private:
            Iterator<T> data;
    
        public:
                    
            T getData() {
                    return *(data.getdata());   // access private member of data
            }
    };
    
    #endif
    iterator
    Code:
    #ifndef ITERATOR_H
    #define ITERATOR_H
    
    template <class T>
    class Iterator
    {
        //friend class List<T>; // compile error
        
        private:
            T* dataPtr;
    
            T* getdata() {
                    return dataPtr;
            }
    
            public:
            Iterator() {
                    dataPtr = NULL;
            }
    
    };
    
    #endif

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    No declaration for List is present in iterator.h, so naturally the compiler won't recognize a friend declaration. You can either include list.h in iterator.h, or create a forward declaration for list in iterator.h to bring a declaration within scope.
    My best code is written with the delete key.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Code:
    template <class T> class B; // forward decl.
    
    template <class T>
    class A
    {
        T t;
    
    public:
        void Test(const B<T> &b) {t = b.t;}
    };//A
    
    template <class T>
    class B
    {
        friend class A<T>; // friend decl.
        T t;
    };//B
    Now you have an example of a forward and friend template class declaration.

    gg

  6. #6
    Registered User
    Join Date
    May 2003
    Posts
    82
    ahh... forward declaration. I think that was what I was looking for.

    In iterator.h, before the class, I added
    Code:
    template<class T>
    class List;
    And now it works like I wanted it to. The depressing thing is that I think I did that exact same thing earlier in VC++ 6.0 and it gave me an error. Or maybe it was just a typo on my part.

    Either way, thank you Prelude and Codeplug.

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >The depressing thing is that I think I did that exact same thing earlier in VC++ 6.0 and it gave me an error.
    How is that depressing? VC++ 6.0 sucks and it's not your fault.
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    May 2003
    Posts
    82
    How is that depressing?
    Its depressingly consistent. My data structs teacher is keeps accusing my of slamming my hand in the drawer by making all the assignments more complicated than necessary.
    I've been trying to grok all of Accelerated C++, so I've been kinda out in left-field playing with generic programming, which was beyond the scope of the class.
    I'm just thinking of the look on his face when I tell him I broke the compiler. But finals are next week, so all is good.

    Thanks again for your help. After I got home I got my code running on dev-c++, so I should be set.

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I did the example in VC++ 6.0

    gg

  10. #10
    Registered User
    Join Date
    May 2003
    Posts
    82
    If you break it up into a driver and seperate headers for each class it no longer works.

  11. #11
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Code:
    // a.h
    template <class T> class B; // forward decl.
    
    template <class T>
    class A
    {
        T t;
    
    public:
        void Test(const B<T> &b) {t = b.t;}
    };
    
    ***************************************************
    
    // b.h
    template <class T> class A; // forward decl.
    
    template <class T>
    class B
    {
        friend class A<T>;
        T t;
    };
    
    ***************************************************
    
    // main.cpp
    #include "b.h"
    #include "a.h"
    
    int main()
    {
        A<int> a;
        B<int> b;
    
        a.Test(b);
    
        return 0;
    }//main
    Works fine.

    gg

  12. #12
    Registered User
    Join Date
    May 2003
    Posts
    82
    ah... you need two forward declarations.
    /me takes double dose of Flinstone Kids Obvious Pills (tm)

    This changes things. Danke.

    EDIT:
    wait, I spoke too soon.
    debugging....

    EDIT of the EDIT:
    d'oh, typo. had an extra set of brackets on the forward declaration. But now both your example and my actual List class are working. My fault, not VC++'s.
    Thank you again.
    Last edited by AH_Tze; 05-19-2004 at 09:31 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  2. template class default constructor problem
    By kocika73 in forum C++ Programming
    Replies: 3
    Last Post: 04-22-2006, 09:42 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Instantiating a template class
    By NullS in forum C++ Programming
    Replies: 11
    Last Post: 02-23-2005, 10:04 AM
  5. Operator overloading in template classes
    By moejams in forum C++ Programming
    Replies: 5
    Last Post: 07-21-2003, 05:16 PM