TigerCode TigerCode - 1 month ago 15
C++ Question

C++ - Assignment of raw pointers to unique_ptr nodes in a Linked List

I'm trying to figure out how to update my tail raw pointer to a new tail after removing a node in my linked list. (is homework)

I've defined the head and tail as

std::unique_ptr<Node> head ;
Node* tail ;


and in my function for removing a node from the back I have the following implementation.

int Deque::remove_back(){
if (empty()) {throw std::runtime_error(std::string("Empty"));};

std::unique_ptr<Node> old;

Node* p = head.get();

int return_value = tail->val;

while (p->next != tail)
{p = p->next)}

old = move(tail);
tail = p;

return return_value;
}


So tail is a raw pointer of type Node.
P is a raw pointer of type Node.

Head is a unique pointer of type Node.

I'm setting p = head.get()

so now p points to the head

p = p->next should be iterating down my nodes.

The problem is that
p->next != tail


p->next is a pointer to the next node following whatever p is.

I'm trying to set a pointer to a node to be equal to a raw pointer of type node (tail).

Its telling me I can't do this.

I believe its due to p->next not changing into an owning pointer instead of the observing one I declared it to be.

Errors:

Deque.cpp|68|error: no match for 'operator!=' (operand types are 'std::unique_ptr<Node>' and 'Node*')|

Deque.cpp|69|error: cannot convert 'std::unique_ptr<Node>' to 'Node*' in assignment|

Deque.cpp|71|error: no match for 'operator=' (operand types are 'std::unique_ptr<Node>' and 'std::remove_reference<Node*&>::type {aka Node*}')|

Answer

The error messages imply that Node::next is a std::unique_ptr<Node>. You cannot compare/assign a std::unique_ptr directly to a raw pointer. You need to use the std::unique_ptr::get() method instead:

while (p->next.get() != tail) {
    p = p->next.get();
}

Also, when assigning p as the new tail, you are not resetting p->next to nullptr, so it will still be pointing at the old node that is no longer valid.

That being said, it really doesn't make sense to use std::unique_ptr in a linked-list implementation to begin with. If you want automatic destruction of nodes, you should wrap the list inside of a class that destroys the nodes when itself is destroyed, and then remove_back() will have to manually destroy the node being removed.

The STL already has such classes available: std::list (double linked) and std::forward_list (single linked). You should be using them instead of a manual implementation.