Рассмотрим упрощенной реализацию связанный списка в 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
{
}
};
}
Это будет работать, но меня больше интересует решение 'std :: default_delete' – Zereges