2016-11-11 3 views
0

Рассмотрим упрощенной реализацию связанный списка в C++ 11частичной специализации вложенного типа в станде

template<typename T> 
struct list 
{ 
    struct node 
    { 
     T value; 
     std::unique_ptr<node> next; 
    }; 
    std::unique_ptr<node> root; 
}; 

Теперь, если я связан список, который чистит себя в деструкторе с помощью std::unique_ptr «s деструктор. Уничтожение может быть рекурсивным, если компилятор недостаточно умен в оптимизации. Если бы у нас были элементы триллионов в нашем списке, это может быть проблема (переполнение стека).

Таким образом, чтобы помочь компилятору я бы не использовать std::default_delete для std::unique_ptr, а принести свою собственную реализацию

template<typename T> 
struct my_list_delete 
{ 
    void operator()(T* ptr) const 
    { 
     std::stack<T*> nodes; 
     // use explicit stack instead of call stack in recursion 
    } 
}; 

И все узлы были бы std::unique_ptr<node, my_list_delete<node>>. Это хорошо, но я должен написать больше кода для каждого std::unique_ptr У меня есть. Вместо этого я мог бы частично специализировать std :: default_delete!

namespace std 
{ 
template<typename T> 
struct default_delete<typename list<T>::node> 
{ 
    void operator()(typename list<T>* node) const 
    { 
    } 
}; 
} 

Но это не сработает. До тех пор, как я знаю, типа, используемый для создания экземпляра списка, я могу подключить что Но если я хочу, чтобы сделать его универсальным, я застрял на

ошибки C2764: «T»: параметр шаблона не используется или выводимым по частичной специализации 'std::default_delete<list<T>::node>'

У меня есть способ обойти это в C++ 11? Я думал об использовании SFINAE

namespace std 
{ 
template<typename T, typename = std::enable_if</*T is list*/>::type> 
struct default_delete<T> 
{ 
    void operator()(T* node) const 
    { 
    } 
}; 
} 

ответ

1

простое решение было бы написать, используя объявление для этого типа:

using node_ptr = std::unique_ptr<node, my_list_delete<node>>; 
+0

Это будет работать, но меня больше интересует решение 'std :: default_delete' – Zereges

1

Вы можете «unnest» внутренний класс:

template <typename T> struct list_node { 
    T value; 
    std::unique_ptr<node> next; 
}; 

template<typename T> struct list { 
    using node = list_node<T>; 
    std::unique_ptr<node> root; 
}; 

namespace std { 
    template<typename T> struct default_delete<list_node<T>> { 
     void operator()(typename list<T>* node) const { } 
    }; 
} 

default_delete<list<T>::node>()(...); // works 
Смежные вопросы