0
class Node{
    template<class T>
    friend class DLList; 
    private:
    T data;
    Node* next;
    Node* prev;
    public:

    Node():next(nullptr),prev(nullptr){}
    Node(T val):next(nullptr),prev(nullptr),data(val){}
    Node(const Node<T>& rhs):next(nullptr),prev(nullptr),data(rhs.data){}
    ~Node();
};

I keep getting the T is an unknown type someone please explain to me why.

P. Tarala
  • 55
  • 5
  • `class Node` currently isn't templated. – user4581301 Oct 25 '19 at 01:57
  • There is a bit more subtlety coming around the corner. Some of it is covered here: [Class template with template class friend, what's really going on here?](https://stackoverflow.com/questions/8967521/class-template-with-template-class-friend-whats-really-going-on-here) I'm looking to see if I can find a more complete answer to the problem you'll run into next. – user4581301 Oct 25 '19 at 02:02
  • Haven't found one yet. but `friend class DLList;` as suggested by the answer linked above probably won't be enough because odds are good that by the time the compiler reaches it, it won't know that `DLList` is a template yet. You may need a `template class DLList;` to forward declare that `DLList` is a template. – user4581301 Oct 25 '19 at 02:06

1 Answers1

0

With

class Node{
    template<class T>
    friend class DLList; 

the only thing that is templated is the friend. Node is not templated.

Solution: Make Node a template as well

template<class T>
class DLList; // declare DLList is a template so that it's a template when friended

template<class T>
class Node{

    friend class DLList<T>; // Node is now a friend of DLList<T> and no other DLLists 
private:
    T data;
    Node* next;
    Node* prev;
public:

    Node():next(nullptr),prev(nullptr){} // I don't recommend having this constructor.
                                         // If T doesn't have a default constructor, 
                                         // the program will not compile and the error 
                                         // messages can be quite inscrutable.
    Node(T val):data(val), next(nullptr),prev(nullptr){}
                                         // I moved data to the front of the line because 
                                         // the members are always initialized in the 
                                         // same order as they are defined no matter the 
                                         // order they are in in the initializer list. It 
                                         // doesn't matter here, but I see it as a 
                                         // sanitation issue.
    Node(const Node<T>& rhs):data(rhs.val), next(nullptr),prev(nullptr){}
                                         // corrected this constructor to use the correct 
                                         // input value. I don't recommend having this 
                                         // constructor. 1) You Probably don't need it. 
                                         // the default constructor should be good enough
                                         // and 2) this isn't really a copy. 
    ~Node();
};

template<class T>
class DLList // now we define DLList for real.
{

};

But... There is a better way to do this.

We can make the Node a private member of the DLList class. Now that only DLList can see Nodes, we can make all of the Node members public.

template<class T>
class DLList
{
private:
    class Node{
    public:
        T data;
        Node* next;
        Node* prev;

        Node(const T & val):data(val), next(nullptr),prev(nullptr){}
        Node(const T & val,  Node* p, Node* n):data(val), next(p), prev(n){}
                                         // Having a constructor that sets the prev and 
                                         // next pointers makes insertion logic just a 
                                         // bit easier later.
        ~Node();
    };

    // private DLList stuff goes here
public: 
    // public DLList stuff goes here

};

Why is this a good idea? Encapsulation. No one outside if DLList should know that Node even exists. They should certainly never be allowed to get their hands on one. Some idiot could delete one without properly removing it. They could accidentally mangle it. Don't give them the chance. Give them iterators and give them data. Never give them a Node.

user4581301
  • 33,082
  • 7
  • 33
  • 54