Consider the following singly linked list implementation:
struct node {
std::unique_ptr<node> next;
ComplicatedDestructorClass data;
}
Now, suppose I stop using some std::unique_ptr<node> head
instance that then goes out of scope, causing its destructor to be called.
Will this blow my stack for sufficiently large lists? Is it fair to assume that the compiler will do a pretty complicated optimization (inline unique_ptr
's destructor into node
's, then use tail recursion), which gets much harder if I do the following (since the data
destructor would obfuscate next
's, making it hard for the compiler to notice the potential reordering and tail call opportunity):
struct node {
std::shared_ptr<node> next;
ComplicatedDestructorClass data;
}
If data
somehow has a pointer to its node
then it might even be impossible for tail recursion (though of course we should strive to avoid such breaches of encapsulation).
In general, how is one supposed to destroy this list otherwise, then? We can't traverse through the list and delete the "current" node because shared pointer doesn't have a release
! The only way is with a custom deleter, which is really smelly to me.