(模板)重新绑定<>有什么作用?

what does (template) rebind<> do?

本文关键字:什么 作用 gt lt 新绑定 绑定 模板      更新时间:2023-10-16

试图了解更多关于标准库是如何实际实现的,我正在检查visual studio中的所有容器。这里我看到了一些奇怪的结构:

std::list<>的某个基类中找到以下类型定义

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

其中"_Alloc"对应于分配器模板实参(而_Ty是所包含的类型)。我很难找到一个很好的解释这个"关键字"。到目前为止,我发现最好的事情是它是分配器接口的一部分。尽管cppreference也不能很好地解释这个

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

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

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

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

  1. 由于rebind_A的成员模板,_A是模板参数,因此rebind成为依赖名称。为了表明依赖名称是模板,需要以template作为前缀。如果没有template关键字,<将被认为是小于操作符。
  2. 名称other也依赖于模板参数,也就是说,它也是一个依赖名称。如果依赖名称是类型,则需要使用typename关键字。

rebind用于为不同于所实现容器的元素类型的类型分配内存。摘自这篇MSDN文章:

例如,给定A类型的分配器对象al,可以用表达式分配_Other类型的对象:
A::rebind<Other>::other(al).allocate(1, (Other *)0)

或者,您可以通过写入类型来命名它的指针类型:

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

stdc++代码中的示例:/usr/include/4.8/ext/new_allocator.h

rebind定义为allocator类的结构成员;该结构体定义了成员other,该成员定义为专为不同实参类型的分配器的实例(other成员定义了可以创建不同类型对象的分配器类)

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

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

你会看到

rebind<…>实际上是类allocator的成员,它是STL的一部分,不提供实现的源代码。

如你所见,rebind<…>也是一个模板,它需要一个类型来让分配器类知道我的rebind成员中有什么。

回到你的声明:typepedef typename _Alloc::template reind<_Ty>::other _Alty;如果你省略了模板:typedef typename _Alloc::rebind<_Ty>::other _Alty;你可以很容易地理解rebind是_Alloc的成员,但是编译器不能理解。

考虑到rebind作为模板的性质,需要对模板rebind<_Ty>进行处理作为一个整体而不是两个部分。