Thread: template and friend class

  1. #1
    Registered User
    Join Date
    Dec 2006
    Posts
    40

    template and friend class

    I hope that it is obvious what I am trying to do below. I want my Linked List nodes to be both templates and a friend class with my Linked List class. My compiler tells me:

    Code:
    error C2989: 'LinkedList' : class template has already been declared as a non-class template
    Anyway, here's all the code:

    Code:
    #ifndef CS240_LINKED_LIST_H
    #define CS240_LINKED_LIST_H
    
    #include <String>
    
    //! LLNode implements a doubly-linked list node
    template <class T>
    class LLNode {
    	friend class LinkedList;  //!< LinkedList can access private members of LLNode
    private:
    	T * value;        		//!< value stored in the node
    	LLNode * prev;            //!< pointer to previous node in the list
    	LLNode * next;            //!< pointer to next node in the list
    public:
    	//!  Constructor
    	LLNode(const T * v, LLNode * p, LLNode * n) :
    	  value(v), prev(p), next(n)
    	{
    	}
    	
    	//! Copy Constructor SHALLOW COPY and does not free memory
    	//!Feel free to change this function(IE, to a deep copy).
    	LLNode(const LLNode<T> & other) : 
    	   value(other.value),prev(other.prev),next(other.next)
    	{
    		if(other.next!=NULL)
    			next=new LLNode(*other.next);
    	}
    
    	//!  Read-only public methods for use by clients of the LinkedList class
    	const T * GetValue() const
    	{
    	  return value;
    	}
    
    
    	LLNode * GetPrevious()const
    	{
    	  return prev;
    	}
    
    
    	LLNode * GetNext()const
    	{
    	  return next;
    	}
    	
    	//! Assignment operator makes a SHALLOW COPY and does not free memory
    	//!Feel free to change this function(IE, to a deep copy).
    	LLNode<T> & operator=(const LLNode<T> & other)
    	{
    		if(this!=&other)
    		{
    			value=other.value;
    			prev=other.prev;
    			next=other.next;
    		}
    		return *this;
    	}
    };
    
    
    //! LinkedList implements a doubly-linked list
    template <class T>
    class LinkedList
    {
    private:
    	LLNode<T> *LLRoot;
    	int size;
    	void makeCopy(const LinkedList<T> &other)
    	{
    		if(other.size>0)
    		{
    			LLRoot= new LLNode(*other.LLRoot);
    			size=other.size;
    		}
    		else
    		{
    			LLRoot=NULL;
    			size=0;
    		}
    	}
    	
    	void deleteAll(LLNode<T> * current)
    	{
    		if(current==NULL)
    			return;
    		deleteAll(current->next);
    
    		delete current;
    	}
    	
    public:
    
    	//!  No-arg constructor.  Initializes an empty linked list
    	LinkedList()
    	{	
    		LLRoot=NULL;
    		size=0;
    	}
    
    
    	//!  Copy constructor.  Makes a complete copy of its argument
    	LinkedList(const LinkedList<T> & other)
    	{
    		makeCopy(other);
    	}
    
    
    	//!  Destructor
    	~LinkedList()
    	{
    		Clear();
    	}
    
    
    	//! Assignment operator.  Makes a complete copy of its argument
    	//! @return A reference to oneself
    	LinkedList<T>& operator =(const LinkedList<T> & other)
    	{
    		if(this!=&other)
    		{
    			Clear();
    			makeCopy(other);
    		}
    		return *this;
    	}
    
    
    	//!  @return true if the list is empty, or false if the list is not empty
    	bool IsEmpty() const
    	{
    		if(LLRoot==NULL && size==0)
    			return true;
    		return false;
    	}
    
    
    	//!  Removes all values from the list
    	void Clear()
    	{
    		deleteAll(LLRoot);
    		size=0;
    		LLRoot=NULL;
    	}
    
    
    	//!  @return the number of values in the list
    	int GetSize() const
    	{
    		return size;
    	}
    
    	//!  @return a pointer to the first node in the list, or NULL if the list is empty
    	LLNode<T> * GetFirst()const
    	{
    		return LLRoot;
    	}
    
    	//!  @returns a pointer to the last node in the list, or NULL if the list is empty
    	LLNode<T> * GetLast()const
    	{
    		if(LLRoot==NULL)
    			return NULL;
    
    		LLNode *LLCurrent=LLRoot;
    
    		while(LLCurrent->next!=NULL)
    		{
    			LLCurrent = LLCurrent->next;
    		}
    		return LLCurrent;
    	}
    
    	//!  Inserts value v into the list after node n
    	//!  
    	//!  @param v The new value being inserted
    	//!  @param n A node that is already in the list after which the new node should 
    	//!      be inserted.
    	//!      If n is NULL, the new node should be inserted at the beginning of the list.
    	//!
    	//!  @return a pointer to the newly inserted node
    	LLNode<T> * Insert(const T * v, LLNode<T> * n)
    	{
    		LLNode<T> *newNode = NULL;
    		if(n==NULL)
    		{
    			newNode= new LLNode<T>(v,NULL, LLRoot);
    			if(LLRoot==NULL)
    				LLRoot=newNode;
    			else
    				LLRoot->prev=newNode;
    				LLRoot=newNode;
    		}
    		else
    		{
    			newNode = new LLNode(v,n,n->next);
    			if(n->next!=NULL)
    				n->next->prev=newNode;
    			n->next=newNode;
    		}
    		size++;
    		return newNode;
    	}
    
    	//! Searches for the first occurrence of value v that appears in the list 
    	//!   after node n
    	//!   
    	//!  @param v The value being searched for
    	//!  @param n The node in the list after which the search should begin.
    	//!      If n is NULL, the list should be searched from the beginning.
    	//!
    	//!  @return a pointer to the node containing v, or NULL if v is not found
    	LLNode<T> * Find(const T & v, LLNode<T> * n) const
    	{
    		LLNode *LLCurrent;
    
    		if(n==NULL)
    			LLCurrent=LLRoot;
    		else if(n->next==NULL)
    			return NULL;
    		else
    			LLCurrent=n->next;
    
    		while(LLCurrent && LLCurrent->value.compare(v)!=0)
    		{
    			LLCurrent = LLCurrent->next;
    		}
    		return LLCurrent;
    	}
    
    
    	//!  Removes node n from the list
    	//!  
    	//!  @param n The node being removed from the list
    	void Remove(LLNode<T> * n)
    	{
    		if(n->next==NULL && n->prev==NULL)
    		{
    			LLRoot=NULL;
    			size=0;
    		}
    		else if(n==LLRoot && size>=2)
    		{
    			LLRoot->next->prev=NULL;
    			LLRoot=n->next;
    			size--;
    		}
    		else if(n->next==NULL && size>=2)
    		{
    			n->prev->next=NULL;
    			size--;
    		}
    		else
    		{
    			n->prev->next=n->next;
    			n->next->prev=n->prev;
    			size--;
    		}
    		delete n;
    	}
    
    	static bool Test(std::ostream & os)
    	{
    		os<<"\nBeginning Linked List Tests:\n";
    		bool success = true;
    		LinkedList<string> list;
    		list.Insert(new string("Home"), NULL);
    		list.Insert(new string("School"), NULL);
    		list.Insert(new string("Church"), NULL);
    		list.Insert(new string("Hospital"), NULL);
    		if(!list.Find("Home", NULL))
    		{
    			success = false;
    			os<< "\tContains() failed\n";
    		}
    		if(list.GetSize() != 4)
    		{
    			success = false;
    			os<< "\tSize() failed\n";
    		}
    		
    		return success;			
    	}
    };
    
    
    #endif
    Thanks for the help!

  2. #2
    Registered User
    Join Date
    Dec 2006
    Posts
    40
    Nobody can help me?

    Ah... crap.

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by black_spot1984 View Post
    Nobody can help me?

    Ah... crap.
    If you're gonna give up after 15 minutes I guess our lives are a bit easier...
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    The only piece of code that seems to maybe have that error is:
    Code:
    friend class LinkedList<;  //!< LinkedList can access private members of LLNode
    I believe you need something like this:
    Code:
    template <typename T>
    class LLNode {
     friend class LinkedList<T>;
     ...
    };
    Or something like this so LLNode knows that LinkedList is a template class

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  2. Template Class as a friend of another class
    By Bnchs in forum C++ Programming
    Replies: 2
    Last Post: 12-02-2007, 05:25 PM
  3. Replies: 8
    Last Post: 07-24-2006, 08:14 AM
  4. Declare a template class as a friend?
    By AH_Tze in forum C++ Programming
    Replies: 11
    Last Post: 05-19-2004, 09:24 PM
  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