std :: scoped_allocator_adapter的目的是什么? [英] What is the purpose of std::scoped_allocator_adapter?

查看:253
本文介绍了std :: scoped_allocator_adapter的目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 11标准中,我们在动态内存管理库中拥有 std :: scoped_allocator_adapter 。这个类最重要的用例是什么?

In the C++11 standard we have std::scoped_allocator_adapter in the dynamic memory management library. What are the most important use cases of this class?

推荐答案

如果你想要一个容器的字符串,并希望使用相同的分配器容器及其元素分配在相同的领域,如TemplateRex描述),那么你可以手动做到:

If you want a container of strings and want to use the same allocator for the container and its elements (so they are all allocated in the same arena, as TemplateRex describes) then you can do that manually:

template<typename T>
  using Allocator = SomeFancyAllocator<T>;
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
using Vector = std::vector<String, Allocator<String>>;

Allocator<String> as( some_memory_resource );
Allocator<char> ac(as);
Vector v(as);
v.push_back( String("hello", ac) );
v.push_back( String("world", ac) );

然而,这是尴尬和容易出错的,因为太容易意外插入一个字符串不使用相同的分配器:

However, this is awkward and error-prone, because it's too easy to accidentally insert a string which doesn't use the same allocator:

v.push_back( String("oops, not using same memory resource") );

std :: scoped_allocator_adaptor 的目的是以自动地将分配器传播到它构造的对象(如果它们支持利用分配器进行构造)。因此上面的代码将变成:

The purpose of std::scoped_allocator_adaptor is to automatically propagate an allocator to the objects it constructs if they support construction with an allocator. So the code above would become:

template<typename T>
  using Allocator = SomeFancyAllocator<T>;
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
using Vector = std::vector<String, std::scoped_allocator_adaptor<Allocator<String>>>;
                                   /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
Allocator<String> as( some_memory_resource );
Allocator<char> ac(as);
Vector v(as);
v.push_back( String("hello") );  // no allocator argument needed!
v.push_back( String("world") );  // no allocator argument needed!



现在向量的分配器被自动用来构造它的元素,即使插入的对象, String(hello) String(world)不使用相同的分配器构造。由于 basic_string 可以从 const char * 隐式构造,最后两行可以进一步简化:

Now the vector's allocator is automatically used to construct its elements, even though the objects being inserted, String("hello") and String("world"), are not constructed with the same allocator. Since basic_string can be implicitly constructed from const char* the last two lines can be simplified even further:

v.push_back( "hello" );
v.push_back( "world" );

这更简单,更容易阅读,并且不易出错,感谢 scoped_allocator_adaptor 自动使用向量的分配器构建元素。

This is much simpler, easier to read, and less error-prone, thanks to scoped_allocator_adaptor constructing the elements with the vector's allocator automatically..

当向量要求其分配器构造一个元素为 obj 它调用:

When the vector asks its allocator to construct an element as a copy of obj it calls:

std::allocator_traits<allocator_type>::construct( get_allocator(), void_ptr, obj );

通常,分配器的 construct()然后调用如下:

Normally the allocator's construct() member would then call something like:

::new (void_ptr) value_type(obj);

但如果 allocator_type $ c> scoped_allocator_adaptor< A> ,那么它使用模板元编程来检测是否可以用适配类型的分配器构造 value_type 。如果 value_type 在其构造函数中未使用分配器,则适配器会执行以下操作:

But if the allocator_type is scoped_allocator_adaptor<A> then it uses template metaprogramming to detect whether value_type can be constructed with an allocator of the adapted type. If value_type doesn't use allocators in its constructors then the adaptor does:

std::allocator_traits<outer_allocator_type>::construct(outer_allocator(), void_ptr, obj);

这将调用嵌套分配器的 construct() member,它使用像placement new这样的东西,如上所述。但是如果对象支持在其构造函数中接受分配器,那么<​​code> scoped_allocator_adaptor< A> :: construct()可以:

And that will call the nested allocator's construct() member, which uses something like placement new, as above. But if the object does support taking an allocator in its constructor then the scoped_allocator_adaptor<A>::construct() does either:

std::allocator_traits<outer_allocator_type>::construct(outer_allocator(), void_ptr, obj, inner_allocator());

或:

std::allocator_traits<outer_allocator_type>::construct(outer_allocator(), void_ptr, std::allocator_arg, inner_allocator(), obj);

适配器在其嵌套分配器上调用 construct()时传递额外的参数,以便使用分配器构造对象。 inner_allocator_type scoped_allocator_adaptor 的另一个特殊化,因此如果元素类型也是一个容器,它使用相同的协议构造 元素,并且分配器可以传递到每个元素,即使你有容器的容器的容器等。

i.e. the adaptor passes additional arguments when it calls construct() on its nested allocator, so that the object will be constructed with the allocator. The inner_allocator_type is another specialization of scoped_allocator_adaptor, so if the element type is also a container, it uses the same protocol to construct its elements, and the allocator can get passed down to every element, even when you have containers of containers of containers etc.

适配器的目的是包装现有的分配器并执行构造函数参数的所有元编程和操作,以将分配器从容器传播到其子容器。

So the purpose of the adaptor is to wrap an existing allocator and perform all the metaprogramming and manipulation of constructor arguments to propagate allocators from a container to its children.

这篇关于std :: scoped_allocator_adapter的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆