std

时间:2016-11-11 09:40:20

标签: c++11

考虑使用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
    {
    }
};
}

2 个答案:

答案 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)}