(模板)重新绑定<>有什么作用?
what does (template) rebind<> do?
试图了解更多关于标准库是如何实际实现的,我正在检查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
指定相应的类型。现在,在这个声明中有一些语法上的麻烦:
- 由于
rebind
是_A
的成员模板,_A
是模板参数,因此rebind
成为依赖名称。为了表明依赖名称是模板,需要以template
作为前缀。如果没有template
关键字,<
将被认为是小于操作符。 - 名称
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>进行处理作为一个整体而不是两个部分。
- archive_read_support_filter_all() 有什么作用?
- 当我们为(;;) 写作时,它做了什么?for 循环中的双分号有什么作用?
- 这个递归函数有什么作用?运行时的复杂性是多少?
- DrawShadow 中的 Elevation 究竟有什么作用?
- 测试"stream >> char"有什么作用?
- "uFlags &= ~CHN_PANNING"命令有什么作用?
- GCC 的 -Wpsabi 选项究竟有什么作用?压制它意味着什么?
- int** a = new int*[n]();这个函数有什么作用?
- C++ 此函数调用之前的(void)有什么作用?
- i+=(i&-i) 有什么作用?它是便携式的吗?
- 这个size_t在 lambda 中有什么作用?C++代码
- 数组下标运算符 ([ ]) 对数组有什么作用?
- 结构之外的节点 * head 有什么作用?
- 重载括号运算符有什么作用?
- clang的"-Ofast"选项在实践中有什么作用,特别是对于与gcc的任何差异?
- std::make_unique_for_overwrite() 对 std::make_unique() 有什么作用?
- 运算符 delete[] 有什么作用?
- 下面的代码有什么作用?c++
- 这个陈述'p = I.ptr<uchar>(i);有什么作用?
- 这个嵌套的名称空间定义有什么作用