Розглянемо таку реалізацію списку, що стосується окремо:
struct node {
std::unique_ptr<node> next;
ComplicatedDestructorClass data;
}
Тепер, припустимо, я припиняю використовувати якийсь std::unique_ptr<node> headекземпляр, який потім виходить за межі, викликаючи виклик його деструктора.
Чи вдасться це підірвати мій стек для достатньо великих списків? Чи справедливо припустити, що компілятор зробить досить складну оптимізацію (вбудований unique_ptrдеструктор в node's, а потім використовувати хвостову рекурсію), що стає набагато складніше, якщо я виконую наступне (оскільки dataдеструктор заблукає next, робить це важким щоб компілятор помітив потенційну можливість упорядкування та виклику хвоста):
struct node {
std::shared_ptr<node> next;
ComplicatedDestructorClass data;
}
Якщо dataякимось чином є вказівник на його, nodeто для рецидиву хвоста це може бути навіть неможливим (хоча, звичайно, ми повинні прагнути уникати таких порушень інкапсуляції).
Загалом, як тоді знищити цей список? Ми не можемо пройти через список та видалити "поточний" вузол, оскільки спільний вказівник не має release! Єдиний спосіб - із користувацьким делетером, який мені справді смердючий.
gcc -O3не вдалося оптимізувати хвостову рекурсію (на складному прикладі).