试图更多地了解标准库是如何实现的我正在检查visual studio中的所有容器。在这里我看到了一些奇怪的结构:
在std::list<>
的某个基类中找到以下typedef
typedef typename _Alloc::template rebind<_Ty>::other _Alty;
其中“_Alloc”对应于allocator模板参数(和_Ty包含的类型)。我很难找到这个“关键字”的好解释。到目前为止,我发现最好的是它是分配器接口的一部分。虽然即使cppreference解释这个也不是很好。
这template rebind<>
做了什么?为什么在那个地方有必要呢?
答案 0 :(得分:18)
_Alloc
模板用于获取某种类型的对象。容器可能具有分配不同类型的对象的内部需求。例如,当您有std::list<T, A>
时,分配器A
用于分配类型为T
的对象,但std::list<T, A>
实际上需要分配某些节点类型的对象。调用节点类型_Ty
,std::list<T, A>
需要获取正在使用_Ty
提供的分配机制的A
个对象的分配器。使用
typename _A::template rebind<_Ty>::other
指定相应的类型。现在,这个声明中有一些语法上的烦恼:
rebind
是_A
的成员模板,_A
是模板参数,因此rebind
成为从属名称。要指示依赖名称是模板,需要以template
为前缀。如果没有template
关键字,则<
将被视为小于运营商。other
也取决于模板参数,即它也是一个从属名称。要指示从属名称是类型,需要typename
关键字。答案 1 :(得分:3)
rebind
用于为与正在实现的容器的元素类型不同的类型分配内存。取自this MSDN article:
例如,给定A类型的分配器对象,可以使用以下表达式分配_Other类型的对象:
A::rebind<Other>::other(al).allocate(1, (Other *)0)
或者,您可以通过写入类型来命名其指针类型:
A::rebind<Other>::other::pointer
答案 2 :(得分:1)
stdc ++代码中的示例:/usr/include/4.8/ext/new_allocator.h
rebind被定义为allocator类的结构成员;此结构定义了一个成员其他,它被定义为专门用于不同参数类型的分配器实例(其他成员定义了一个可以创建不同类型的对象)
template<typename _Tp>
class new_allocator
{
public:
...
template<typename _Tp1>
struct rebind
{ typedef new_allocator<_Tp1> other; };
使用时:
typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
分配器的类型引用为
typename _Alloc::template rebind<_Tp>::other
现在,typedef用于定义 _Tp_alloc_type - 然后可以将其用作同一事物的较短名称。
示例用法是在std :: list中,其中内部列表节点也需要其分配器,该分配器是从参数分配器重新定义的。
答案 3 :(得分:0)
请查看此http://www.cplusplus.com/reference/memory/allocator/
你会看到
重新绑定&LT; ...&GT;实际上是类分配器的成员,它是STL的一部分,没有给出实现的源代码。
如你所见,重新绑定&lt; ...&gt;也是一个模板,它应该让分配器类知道我的重新绑定成员中的内容。
回到你的陈述: typedef typename _Alloc :: template rebind&lt; _Ty&gt; :: other _Alty; 如果你省略了模板: typedef typename _Alloc :: rebind&lt; _Ty&gt; :: other _Alty; 你可以很容易地理解rebind是_Alloc的成员,但编译器无法理解。
鉴于rebind作为模板的性质,模板重新绑定&lt; _Ty&gt;需要并得到治疗 整体而言不是两部分。