嵌套类作为模板参数

时间:2015-11-12 17:18:10

标签: c++ templates stl containers

我尝试编写一个自定义STL样式的容器。为简单起见,我们说它是一个列表。我查找了定义这样一个容器的标准方法:

template <typename T, typename A = std::allocator<T> > class mylist;

现在,我想使用嵌套类来管理列表的节点:

(inside mylist)
class node {
    T data;
    node *next;
}

我的理解是,我不需要在template的定义前放置node说明符,因为编译器将为{{1}的每个组合实例化单独的类mylist<T,A>::node模板参数。

但是,现在我需要为类型mylist本身的数据分配内存,而且还需要为它们的包装器T分配内存。因此,我希望默认模板参数的类型为node。但是,那时,std::allocator<mylist<T>::node>尚未被声明,编译器可以理解为难以理解:

mylist

如何解决这个难题?有两个限制因素:

  • 通常情况下,我会在没有完全声明其内容的情况下声明缺少的类。但是,因为它嵌套在我要声明的内容中,所以这不是一个选项。
  • 我需要嵌套error: `mylist' was not declared in this scope ,因为它需要访问node的分配器实例。例如,我在mylist上声明operator=,其中大量内存管理以递归方式发生。对于列表而言这可能有点过分,您可以在node内执行此操作,从而降低mylistnode的参数依赖性,但这对我正在实现的数据结构至关重要。

2 个答案:

答案 0 :(得分:2)

默认分配器的类型参数是什么,只是实际类型无关紧要。您可以使用std::allocator_traits中的rebind_alloc

  

Alloc::rebind<T>::other如果存在,否则Alloc<T, Args>如果此AllocAlloc<U, Args>

得到你需要的东西:

template <typename T, typename A = std::allocator<T> >
class mylist {
    class node { ... };

    using NodeAlloc = typename std::allocator_traits<A>::template rebind_alloc<node>;
};

然后使用NodeAlloc获取node。这样,如果用户未指定分配器,您将获得默认的std::allocator<T>,然后使用std::allocator<node>。这正是您想要的,而不必公开node

答案 1 :(得分:1)

  

我需要嵌套节点,因为它需要访问mylist

的分配器实例

不要太确定。他们可以成为朋友:

template <typename, class> class list;

template <typename T>
struct node {
    // ...
};

template <typename T, class Alloc=std::allocator<T> >
class list {
    friend node<T>;
    // ...
};

如果您不想在文件之外访问node,请在头文件(.h / .hpp)中省略它。