- > `Node` wants a constructor Node(const Type& tp, Node * prev = nullptr, Node * next = nullptr) : element(tp) , prev(prev) , next(next) {} - >What can be simplified `push`s and `pop`s. There is common functionality between a special and common cases. Consider for example `push_front`: after the push a new node would become `head`, no matter what: push_front(const Type& tp) { node = new Node(tp, nullptr, head); if (head == 0) { tail = node; } else { head->prev = node; } head = node; } Other three function can be similarly streamlined. - A copy constructor shares too much code with `push_back`. Consider consolidating the common base. Ditto for a destructor and `clear`. - You may want to assert your invariants: if you have, say, `head == nullptr`, you must also have `tail == nullptr` and `count == 0`.