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> headinstancia 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_ptrdestructor en línea en nodeel, luego usará la recursión de cola), que se vuelve mucho más difícil si hago lo siguiente (ya que el datadestructor ofuscaría nextel 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 dataalguna manera tiene un puntero, nodeentonces 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 -O3no fue posible optimizar una recursión de la cola (en un ejemplo complicado).