[英]Nested class as a template parameter
我尝试编写一个自定义STL样式的容器。 为简单起见,我们说它是一个列表。 我查找了定义这样一个容器的标准方法:
template <typename T, typename A = std::allocator<T> > class mylist;
现在,我想使用嵌套类来管理列表的节点:
(inside mylist)
class node {
T data;
node *next;
}
我的理解是,我不需要在node
定义之前放置template
说明符,因为编译器将为mylist
的模板参数的每个组合实例化单独的类mylist<T,A>::node
。
但是,现在我需要为T
本身的数据分配内存,而且还需要为它们的包装器node
分配内存。 因此,我希望默认模板参数的类型为std::allocator<mylist<T>::node>
。 那时, mylist
还没有被声明,编译器可以理解为难过:
error: `mylist' was not declared in this scope
如何解决这个难题? 有两个限制:
node
,因为它需要访问mylist
的分配器实例。 例如,我在node
上声明了operator=
,其中大量内存管理以递归方式发生。 对于列表来说这可能是过度的,你可以从mylist
做到这一点,从而降低node
对A
的参数依赖性,但这对我正在实现的数据结构至关重要。 默认分配器的类型参数是什么,只是实际类型并不重要。 您可以使用std::allocator_traits
rebind_alloc
:
Alloc::rebind<T>::other
如果存在,否则Alloc<T, Args>
如果这个Alloc
是Alloc<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
。
我需要嵌套节点,因为它需要访问
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
)中省略它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.