但是我怎么知道容器使用哪种分配的,如果它 内部从重新绑定模板参数给定的分配?
始终提供一个Allocator<T>
给构造(其中T
是容器的value_type
)。该容器将它转换为Allocator<U>
是必要的,其中U
是容器的一些内部数据结构。所述Allocator
需要提供这样的转换构造,例如:
template <class T> class allocator {
...
template <class U> allocator(const allocator<U>&);
此外我读C++ 11现在使用范围的分配器,其允许 重用容器的分配器为包含它的容器。
好,更精确地说,C++ 11有一个名为scoped_allocator_adaptor
的分配器适配器:
template <class OuterAlloc, class... InnerAllocs>
class scoped_allocator_adaptor : public OuterAlloc
{
...
};
从C++ 11:
类模板scoped_allocator_adaptor
是一个分配器模板 ,它指定一个容器使用的内存资源(外部分配器)(与任何其他分配器一样)并指定一个内部的 分配器资源被传递给容器内的每个元素 的构造器。该适配器实例化为一个外部和零个或多个内部分配器类型。如果只有一个 分配器类型实例化,所述内分配器成为 scoped_allocator_adaptor
本身,从而使用用于容器相同的分配器 资源和所述容器内的每个元件和,如果 元素本身是CON组tainers,每个它们的元素递归地为 。如果使用多个分配器实例化,则第一个分配器是容器使用的外部分配器,第二个分配器将被传递给容器元素的构造函数 ,如果元素本身是容器,则第三个分配器是 传递给元素的元素,依此类推。如果将容器嵌套 的深度大于分配器的数量,则最后一个分配器 会在单分配器情况下重复使用,对于任何剩余的 递归。 [注意:scoped_allocator_adaptor
源自 外部分配器类型,所以它可以代替大多数表达式中的外部分配器 类型。 - 注完]
所以,只有当您指定一个scoped_allocator_adaptor
作为分配器为您的容器得到作用域分配器行为。
作用域分配器启用容器 的实现如何与不知道作用域容器的实现大致不同?
关键是容器现在通过一个名为allocator_traits
的新类来处理它的分配器,而不是直接处理分配器。而容器必须使用allocator_traits
进行某些操作,例如在容器中构建和销毁value_type
。容器不得直接与分配器通信。
例如,分配器可以提供一种构件称为construct
将使用给定的参数在一定的地址构造类型:
template <class T> class Allocator {
...
template<class U, class... Args>
void construct(U* p, Args&&... args);
};
如果分配器不提供此构件,allocator_traits
将提供一个默认实现。在任何情况下,容器必须构建使用所有value_type
s此construct
功能,但使用它通过allocator_traits
,而不是使用allocator
直接:
allocator_traits<allocator_type>::construct(the_allocator, *ugly details*);
的scoped_allocator_adaptor
定制提供construct
功能,这allocator_traits
将转发到利用uses_allocator
特性并将正确的分配器传递给value_type
构造函数。容器仍然对这些细节无知。容器只需知道它必须使用allocator_traits construct
函数构造value_type
。
容器必须处理的更多细节才能正确处理有状态的分配器。虽然这些细节也通过让容器不作任何假设来处理,但通过allocator_traits
获得所有属性和行为。该容器甚至不能假定pointer
是T*
。而是通过询问allocator_traits
发现它是什么。
简而言之,要构建一个C++ 11容器,请研究allocator_traits
。然后,当客户使用scoped_allocator_adaptor
时,您可以免费获得有限范围的分配器行为。