Рассмотрим следующую реализацию односвязного списка:
struct node {
std::unique_ptr<node> next;
ComplicatedDestructorClass data;
}
Теперь предположим, что я перестал использовать некоторый std::unique_ptr<node> head
экземпляр, который затем выходит из области видимости, вызывая вызов его деструктора.
Будет ли это удар по моему стеку для достаточно больших списков? Справедливо ли предположить, что компилятор будет выполнять довольно сложную оптимизацию (встроенный unique_ptr
деструктор в node
, а затем использовать хвостовую рекурсию), что будет намного сложнее, если я сделаю следующее (поскольку data
деструктор будет запутывать next
, делая его трудным чтобы компилятор заметил потенциальную возможность переупорядочения и возможности хвостового вызова):
struct node {
std::shared_ptr<node> next;
ComplicatedDestructorClass data;
}
Если data
каким-то образом есть указатель на его, node
тогда это может быть даже невозможно для хвостовой рекурсии (хотя, конечно, мы должны стремиться избегать таких нарушений инкапсуляции).
В общем, как можно иначе уничтожить этот список? Мы не можем просмотреть список и удалить «текущий» узел, потому что у общего указателя нет release
! Единственный способ - с помощью пользовательского удалителя, который действительно воняет для меня.
gcc -O3
не удалось оптимизировать хвостовую рекурсию (в сложном примере).