STL Container:构造函数的分配器参数和作用域分配器

STL Container: Constructor#39;s Allocator parameter and scoped allocators(STL Container:构造函数的分配器参数和作用域分配器)
本文介绍了STL Container:构造函数的分配器参数和作用域分配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

There is a template parameter for STL containers to chose a custom allocator. It took a while, but I think I understand how it works. Somehow it isn't really nice because the given allocator type isn't used directly but it is rebound to the allocator of another type. Finally I can work with it.

After reading the API I recognized that there is also the possibility to give allocators as constructor parameter. But how do I know which kind of allocator the container uses, if it internally rebinds the given allocator from the template parameter?

Additionally I read that C++11 now uses scoped allocators which allow to reuse the allocator of a container for its containing containers. How does the implementation of a scoped allocator enabled container roughly differs from one that is not aware of scoped containers?

Unfortunately I wasn't able to find anything that could explain this. Thanks for answers!

解决方案

But how do I know which kind of allocator the container uses, if it internally rebinds the given allocator from the template parameter?

Always supply an Allocator<T> to the constructor (where T is the value_type of the container). The container will convert it to an Allocator<U> is necessary where U is some internal data structure of the container. The Allocator is required to supply such converting constructors, e.g.:

template <class T> class allocator {
    ...
    template <class U> allocator(const allocator<U>&);

Additionally I read that C++11 now uses scoped allocators which allow to reuse the allocator of a container for its containing containers.

Well, to be more precise, C++11 has an allocator adaptor called scoped_allocator_adaptor:

template <class OuterAlloc, class... InnerAllocs>
class scoped_allocator_adaptor : public OuterAlloc
{
    ...
};

From C++11:

The class template scoped_allocator_adaptor is an allocator template that specifies the memory resource (the outer allocator) to be used by a container (as any other allocator does) and also specifies an inner allocator resource to be passed to the constructor of every element within the container. This adaptor is instantiated with one outer and zero or more inner allocator types. If instantiated with only one alloca- tor type, the inner allocator becomes the scoped_allocator_adaptor itself, thus using the same allocator resource for the container and every element within the container and, if the elements themselves are con- tainers, each of their elements recursively. If instantiated with more than one allocator, the first allocator is the outer allocator for use by the container, the second allocator is passed to the constructors of the container’s elements, and, if the elements themselves are containers, the third allocator is passed to the elements’ elements, and so on. If containers are nested to a depth greater than the number of allocators, the last allocator is used repeatedly, as in the single-allocator case, for any remaining recursions. [Note: The scoped_allocator_adaptor is derived from the outer allocator type so it can be substituted for the outer allocator type in most expressions. — end note ]

So you only get the scoped allocators behavior if you specify a scoped_allocator_adaptor as the allocator for your container.

How does the implementation of a scoped allocator enabled container roughly differs from one that is not aware of scoped containers?

The key is that the container now deals with its allocator via a new class called allocator_traits instead of dealing with the allocator directly. And the container must use allocator_traits for certain operations such as constructing and destructing value_types in the container. The container must not talk to the allocator directly.

For example, allocators may provide a member called construct that will construct a type at a certain address using the given arguments:

template <class T> class Allocator {
     ...
    template<class U, class... Args>
        void construct(U* p, Args&&... args);
};

If an allocator does not provide this member, allocator_traits will provide a default implementation. In any event, the container must construct all value_types using this construct function, but using it through allocator_traits, and not using the allocator directly:

allocator_traits<allocator_type>::construct(the_allocator, *ugly details*);

The scoped_allocator_adaptor provides custom construct functions which allocator_traits will forward to which take advantage of the uses_allocator traits and passes the correct allocator along to the value_type constructor. The container remains blissfully ignorant of these details. The container only has to know that it must construct the value_type using the allocator_traits construct function.

There are more details the container must have to deal with to correctly handle stateful allocators. Though these details too are dealt with by having the container not make any assumptions but get all properties and behaviors via allocator_traits. The container can not even assume that pointer is T*. Rather this type is found by asking allocator_traits what it is.

In short, to build a C++11 container, study up on allocator_traits. And then you get scoped allocator behavior for free when your clients use the scoped_allocator_adaptor.

这篇关于STL Container:构造函数的分配器参数和作用域分配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

What is the proper function for comparing two C-style strings?(比较两个 C 风格字符串的正确函数是什么?)
Image Capture with OpenCV - Select Timeout Error(使用 OpenCV 捕获图像 - 选择超时错误)
SHA256 HMAC using OpenSSL 1.1 not compiling(使用 OpenSSL 1.1 的 SHA256 HMAC 未编译)
How to make a Debian package depend on multiple versions of libboost(如何制作一个Debian包依赖于多个版本的libboost)
Why does strcpy_s not exist anywhere on my system?(为什么我系统上的任何地方都不存在 strcpy_s?)
Simplest way to get current time in current timezone using boost::date_time?(使用 boost::date_time 在当前时区获取当前时间的最简单方法?)