考虑以下单链表实现:
struct node {
std::unique_ptr<node> next;
ComplicatedDestructorClass data;
}
现在,假设我停止使用某个std::unique_ptr<node> head
超出范围的实例,从而导致其析构函数被调用。
这会否使我的堆栈大到无法容纳足够大的列表?假设编译器会做一个相当复杂的优化(将inline unique_ptr
的析构函数插入node
,然后使用尾部递归)是否公平,如果我执行以下操作,这会变得更加困难(因为data
析构函数会混淆next
's',使其变得困难)让编译器注意到潜在的重新排序和尾部调用机会):
struct node {
std::shared_ptr<node> next;
ComplicatedDestructorClass data;
}
如果data
某种程度上有指向它的指针,node
那么尾部递归甚至是不可能的(尽管我们当然应该努力避免这种封装破坏)。
通常,那么应该如何销毁该列表呢?我们无法遍历列表并删除“当前”节点,因为共享指针没有release
!唯一的方法是使用自定义删除器,这对我来说真的很臭。
gcc -O3
也无法优化尾部递归(在一个复杂的示例中)。