考虑使用C ++ 11中的简化链表实现
template<typename T>
struct list
{
struct node
{
T value;
std::unique_ptr<node> next;
};
std::unique_ptr<node> root;
};
现在,如果我有链接列表,它会使用std::unique_ptr
的析构函数在析构函数中清除它自己。如果编译器在最优化中不够聪明,那么破坏可能是递归的。如果我们的列表中有数万亿个元素,则可能是一个问题(堆栈溢出)。
所以,为了帮助编译器,我不会将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
{
}
};
}
答案 0 :(得分:1)
一个简单的解决方法是为该类型编写using声明:
using node_ptr = std::unique_ptr<node, my_list_delete<node>>;
答案 1 :(得分:1)
你可以“取消”内部类:
{=SUMIFS($J$27:$J$3001;MONTH($A$27:$A$3001);$N20;$H$27:$H$3001;1)}