Considere la siguiente implementación de lista vinculada individualmente:
struct node {
std::unique_ptr<node> next;
ComplicatedDestructorClass data;
}
Ahora, supongamos que dejo de usar alguna std::unique_ptr<node> head
instancia que luego se sale del alcance y hace que se llame a su destructor.
¿Esto volará mi pila de listas lo suficientemente grandes? ¿Es justo suponer que el compilador hará una optimización bastante complicada ( unique_ptr
destructor en línea en node
el, luego usará la recursión de cola), que se vuelve mucho más difícil si hago lo siguiente (ya que el data
destructor ofuscaría next
el de él, lo que lo dificultaría para que el compilador note la posible oportunidad de reordenamiento y llamada de cola):
struct node {
std::shared_ptr<node> next;
ComplicatedDestructorClass data;
}
Si de data
alguna manera tiene un puntero, node
entonces podría ser imposible para la recursión de la cola (aunque, por supuesto, deberíamos esforzarnos por evitar tales brechas de encapsulación).
En general, ¿cómo se supone que se debe destruir esta lista de otra manera, entonces? No podemos atravesar la lista y eliminar el nodo "actual" porque el puntero compartido no tiene un release
! La única forma es con un eliminador personalizado, lo cual es realmente maloliente para mí.
gcc -O3
no fue posible optimizar una recursión de la cola (en un ejemplo complicado).