2013-01-03 46 views
10

想了解更多有关如何将标准库实际上是实现我检查在Visual Studio中的所有容器..在这里,我看到了一些奇怪的结构:(模板)rebind <>做了什么?

在一些基类std::list<>的下面的typedef发现

typedef typename _Alloc::template rebind<_Ty>::other _Alty; 

其中“_Alloc”与分配器模板参数(和_Ty包含的类型)相对应。我无法找到这个“关键字”的好解释。迄今为止我发现的最好的是它是分配器接口的一部分。虽然即使cppreference也不是很好解释这一点。

这是什么template rebind<>?为什么在那个地方需要?

+0

相关,请参阅[为什么allocator :: rebind必要时,我们有模板模板参数?](http://stackoverflow.com/q/12362363) – jww

回答

14

_Alloc模板用于获取某种类型的对象。容器可能需要分配不同类型的对象。例如,当您有std::list<T, A>时,分配器A用于分配T类型的对象,但std::list<T, A>实际上需要分配某些节点类型的对象。调用节点类型_Ty时,std::list<T, A>需要获取使用A提供的分配机制的_Ty对象的分配器。使用

typename _A::template rebind<_Ty>::other 

指定相应的类型。现在,在这个声明中的一些语法的烦恼:

  1. 由于rebind_A_A成员模板是一个模板参数,rebind成为一个从属名称。要指示从属名称是模板,它需要以template作为前缀。如果没有template关键字,则<将被认为是不到的运算符。
  2. 名称other也依赖于模板参数,即它也是一个从属名称。为了表明从属名称是一个类型,需要typename关键字。
+0

等待,但这将意味着(当列表是'std :: list '); 'rebind '变得多余?因为它会将“T”转换为“T”型? – paul23

+0

@ paul23:如果'_Ty'是模板参数,而不是'typedef _Node <_T> _Ty',可能对确保分配器创建合适的类型有用。虽然我很确定'std :: list '中的'A'需要能够处理'T'对象,不同的分配器可能会被传入。我不确定标准需求。它可能是支持不同类型分配器的扩展。 –

+0

T列表分配包含T作为成员的节点。所以T分配器对它直接无用。相反,它创造了一个新的。您的评论对我没有意义@ paul23 – Yakk

3

rebind用于为与正在实施的容器的元素类型不同的类型分配内存。从this MSDN article采取:

例如,给定类型A的分配器对象人,则可以分配类型_其他的目的与表达:

A::rebind<Other>::other(al).allocate(1, (Other *)0)

或者,也可以通过指定其指针类型写作类型:

A::rebind<Other>::other::pointer

0

请检查该http://www.cplusplus.com/reference/memory/allocator/

你会看到

重新绑定< ...>实际上是类分配的成员是不给执行源代码STL的一部分。

正如你看到的,rebind < ...>也是一个模板,它值得一个类型让分配器类知道什么是我的rebind成员。

回到您的声明: typedef typename _Alloc :: template rebind < _Ty> :: other _Alty; 如果您省略模板: typedef typename _Alloc :: rebind < _Ty> :: other _Alty; 您可以轻松理解rebind是_Alloc的成员,但编译器无法理解。

鉴于rebind是模板的性质,模板rebind < _Ty>是需要的,并且整体而言不是两个部分而是被视为 。

0

实施例STDC的代码++:/usr/include/4.8/ext/new_allocator.h

重新绑定定义为分配器类的结构构件;这种结构限定了构件其他被定义为专用于一个不同的参数类型的分配器的一个实例(其他构件限定,可以创建不同类型的对象的分配器类)

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中,内部列表节点也需要它的分配器,它是从参数分配器重新定义的。

相关问题