0

I am trying to implement a LinkedList for the first time. I almost finished declaring the header file, but I'm getting this one minor error that won't go away. Where I declare the class LinkedList and Iterator below the Node class, I keep getting a message "Redefinition of LinkedList as a differnet kind of symbol" and "Redefinition of Iterator as a different kind of symbol". I tried declaring the classes at the very top of the code like below, moving the friend functions to the private declarations, but nothing seems to work. Can someone point me to what I'm doing wrong. I haven't done much else besides what is below.

class LinkedList;
class Iterator;


template <typename T>
class Node{
public:
    Node(T Data);


private:
    T data;
    Node* next;
    Node* previous;
    friend class LinkedList;  
    friend class Iterator;
};

template<typename T>
class LinkedList {
public:
    LinkedList();
    void pushback(T data); 
    //void insert(Iterator pos, T data);
    ~LinkedList();
    //Iterator begin();
    //Iterator end();

private:
    Node* first;
    Node* last;
    friend class Iterator;
};

template <typename T>
class Iterator{
public:

private:
    Node* position;
    LinkedList* container;
    friend class LinkedList;
};

#endif /* defined(__Linked_List_1__LinkedList__) */
KevinDTimm
  • 14,226
  • 3
  • 42
  • 60
Vivek Reddy
  • 92
  • 1
  • 1
  • 9

3 Answers3

1

You declare LinkedList first as a class and then you define LinkedList as a class template. You should declare the name as class template right away (the same applies for the other declarations):

template <typename> class LinkedList;

When refering to the corresponding class template, e.g., in the friend declaration in Node you'll either need to make the class template a friend, e.g., using

template <class S> friend class LinkedList;

... or, probably, preferable make the corresponding instantiation a friend:

friend class LinkedList<T>;
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • thank you. that fixed the first problem, but all my other declarations of friend have are now saying "elaborated type refers to a template". any idea on what i should do about that? – Vivek Reddy Dec 22 '15 at 22:33
0

You're forward declaring LinkedList as non-templated. Update it to look like:

template<typename T> class LinkedList;

And do the same for Iterator.

Buddy
  • 10,874
  • 5
  • 41
  • 58
0

When you implement LinkedList template class, you should forward typename T into the declaration of Node class since Node is a template, and it need to specify a type name to extend the code for specific type.

My solution is use nested class to solve some complicated dependency problem and do the forwarding for you.( like class A contains type B, class B contains type A)

namespace test{
  template<typename T> class Iterator;

  template<typename T>
  class LinkedList {
  public:
    LinkedList();
    void pushback(T& data);
    void insert(Iterator<T> pos, T& data);
    ~LinkedList();
    Iterator<T> begin();
    Iterator<T> end();
  private:

    struct Node{
      T data;
      Node* next;
      Node* prev;
    }; //Node should be expose to others, try not to complicate friendship

    Node* first;
  };

  template<typename T> class Iterator{
  public:
    T& operator*() const;
    T* operator->() const;
    Iterator<T> next();
  private:
    struct Node{
      T data;
      Node* next;
      Node* prev;
    };
    Node* position;
    LinkedList<T>* container;
    friend class LinkedList<T>;
  };
}

The code above shows you how to use a nested class(or struct,basically struct is a class). You don't expose your node to the user, and iterator should be a pointer like class. I prefer to overload operator * and ->.

It is a good thing to use nested class since it is easy to move a class out then move it in. When you think it is possible to use nested class, you should try.

Scott Deng
  • 119
  • 8