嵌套 class 作为模板参数
Nested class as a template parameter
我尝试编写一个自定义 STL 样式的容器。为了简单起见,假设它是一个列表。我查找了定义此类容器的标准方法:
template <typename T, typename A = std::allocator<T> > class mylist;
现在,我想使用嵌套 class:
来管理列表的节点
(inside mylist)
class node {
T data;
node *next;
}
据我了解,我不需要在 node
的定义前放置一个 template
说明符,因为编译器将实例化单独的 classes mylist<T,A>::node
mylist
模板参数的每个组合。
但是,现在我不仅需要为类型 T
本身的数据分配内存,还需要为它们的包装器 node
分配内存。因此,我希望默认模板参数的类型为 std::allocator<mylist<T>::node>
。不过,那时 mylist
还没有被声明,编译器很不高兴是可以理解的:
error: `mylist' was not declared in this scope
如何解决这一难题?有两个约束:
- 通常,我会在不完整声明其内容的情况下声明丢失的 class。但是,因为它嵌套在我要声明的内容中,所以这不是一个选项。
- 我需要嵌套
node
,因为它需要访问 mylist
的分配器实例。例如,我在 node
上声明了 operator=
,其中大量内存管理是递归发生的。这对于列表来说可能有点矫枉过正,您可以在 mylist
中执行此操作,从而降低 node
对 A
的参数依赖性,但这对于我正在实现的数据结构至关重要.
I need node to be nested as it needs to access the allocator instance of 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
)。
默认分配器的类型参数是什么并不重要,重要的是实际类型。您可以使用 rebind_alloc
来自 std::allocator_traits
:
Alloc::rebind<T>::other
if present, otherwise Alloc<T, Args>
if this Alloc
is 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
.
我尝试编写一个自定义 STL 样式的容器。为了简单起见,假设它是一个列表。我查找了定义此类容器的标准方法:
template <typename T, typename A = std::allocator<T> > class mylist;
现在,我想使用嵌套 class:
来管理列表的节点(inside mylist)
class node {
T data;
node *next;
}
据我了解,我不需要在 node
的定义前放置一个 template
说明符,因为编译器将实例化单独的 classes mylist<T,A>::node
mylist
模板参数的每个组合。
但是,现在我不仅需要为类型 T
本身的数据分配内存,还需要为它们的包装器 node
分配内存。因此,我希望默认模板参数的类型为 std::allocator<mylist<T>::node>
。不过,那时 mylist
还没有被声明,编译器很不高兴是可以理解的:
error: `mylist' was not declared in this scope
如何解决这一难题?有两个约束:
- 通常,我会在不完整声明其内容的情况下声明丢失的 class。但是,因为它嵌套在我要声明的内容中,所以这不是一个选项。
- 我需要嵌套
node
,因为它需要访问mylist
的分配器实例。例如,我在node
上声明了operator=
,其中大量内存管理是递归发生的。这对于列表来说可能有点矫枉过正,您可以在mylist
中执行此操作,从而降低node
对A
的参数依赖性,但这对于我正在实现的数据结构至关重要.
I need node to be nested as it needs to access the allocator instance of
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
)。
默认分配器的类型参数是什么并不重要,重要的是实际类型。您可以使用 rebind_alloc
来自 std::allocator_traits
:
Alloc::rebind<T>::other
if present, otherwiseAlloc<T, Args>
if thisAlloc
isAlloc<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
.