As an exercise in learning C++, I want to build my own forward list using raw pointers and using unique_ptrs. Using raw pointers, I have:
struct node_raw {
node_raw(int data_, node_raw *next_) : data(data_), next(next_) {}
int data;
node_raw *next;
};
Then I can write this
int main() {
node_raw r1{1, nullptr};
node_raw r2{2, &r1};
node_raw r3{3, &r2};
}
to get a forward list: r3 -> r2 -> r1.
Now I want to do the same using unique_ptrs.
struct node_unique {
node_unique(int data_, std::unique_ptr<node_unique> next_)
: data(data_), next(std::move(next_)) {}
int data;
std::unique_ptr<node_unique> next;
};
This is what I have so far for client code:
int main() {
node_unique u1{1, nullptr};
node_unique u2{2, std::make_unique<node_unique>(std::move(u1))};
node_unique u3{3, std::make_unique<node_unique>(std::move(u2))};
}
This gives u3.next->data = 2
, so it seems to work. But is it right? Why do I need std::move
twice to make a new node? Is it now invalid to query u1.data
because it has been moved from? Basically, what is the canonical way to implement a minimal forward list using unique_ptrs?