加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 分配嵌套STL容器时使用哪个分配器?

发布时间:2020-12-16 10:23:02 所属栏目:百科 来源:网络整理
导读:我有一个关于STL类和分配器的问题,这些问题似乎不容易在网上找到.有谁知道在嵌套的STL类中使用了哪个分配器?例如: typedef std::vectorint myvect; //按照后续回复/评论的指示编辑了以下行 typedef std::mapint,myvect,std::lessint,A mymap; //uses my cu
我有一个关于STL类和分配器的问题,这些问题似乎不容易在网上找到.有谁知道在嵌套的STL类中使用了哪个分配器?例如:

typedef std::vector<int> myvect;

//按照后续回复/评论的指示编辑了以下行

typedef std::map<int,myvect,std::less<int>,A> mymap; //uses my custom allocator for map creation

让我们调用默认的分配器D,并假设我有一个自定义分配器A.

如果我做了以下事情将会发生什么:

>创建地图:

mymap mapInstance;

>现在,假设mapInstance [0]存在一个条目,假设我将一个值推入向量:

mapInstance[0].push_back(999);

什么分配器用于向量mapInstance [0]的动态内存?

到目前为止,我的理解是使用了默认的分配器D,但是我想确认不会使用传递给映射的自定义分配器A. (据我所知,只有我使用某种嵌套分配选项才会发生这种情况.)

当然,我理解mapInstance [0]的元数据/头信息是使用自定义分配器A分配的.我关心的是动态内存部分,即d_dataBegin之后的部分.

解决方法

您的问题与 Scoped Allocator Model有关,这是一种分配器设计风格,它自动将容器的分配器传播到容器的元素,这样您就可以确保所有容器的元素都是从同一个分配器中分配的.更多关于以下内容.

回答你的问题:

1)容器默认情况下不使用作用域分配器模型,您必须显式请求它(请参阅下面的scoped_allocator_adaptor)

2)您的嵌套容器是类型std :: vector< int>这意味着它使用默认的std :: allocator< int>分配器,以及该类型的所有实例都是相同的,所以你的问题的答案是它使用标准的分配器 – 哪个是无关紧要的,因为每个std :: allocator< int>是一样的.

这个答案的其余部分只是一个思想实验,你问题的答案如上:vector< int>总是使用std :: allocator< int>

现在,如果您的嵌套类型是std :: vector< int,A1< int>>其中A1< int>是一个自定义分配器,问题变得更有趣.

嵌套容器将使用它构造的分配器,并且您没有显示,因为您已经说过“假设mapInstance [0]存在一个条目”,并且该条目的创建方式决定了它将使用哪个分配器.

如果该条目是这样创建的:

mapInstance[0];

然后该条目是默认构造的,并将使用默认构造的A1< int>.

如果该条目是这样创建的:

A1<int> a1( /* args */ );
myvect v(a1)
mapInstance.insert(mymap::value_type(0,v));

然后该条目将是v的副本,并且在C 03中它的分配器将是v.get_allocator()的副本,但是在C 11中它的分配器将是std :: allocator_traits< A1< int>> ::的副本:: select_on_container_copy_construction(v.get_allocator()),它可能是v.get_allocator()的副本,但可能是不同的东西(例如,默认构造的A1).

(在C 03中,条目的分配器在创建之后无法更改,因此答案将在此处结束,但在C 11中它可以被替换.我假设我们正在讨论C 11以解决此问题的其余部分,因为分配器不是很有趣的是C 03.)

如果该条目被修改如下:

A1<int> a1( /* args */ );
myvect v(a1)
mapInstance[0] = v;

然后,矢量被复制分配给,可能会替换分配器,具体取决于std :: allocator_traits< A1< int>> :: propagate_on_container_copy_assignment :: value的值

如果该条目被修改如下:

A1<int> a1( /* args */ );
mapInstance[0] = myvect(a1);

然后向量移动分配给,具体取决于std :: allocator_traits< A1< int>> :: propagate_on_container_move_assignment :: value的值

如果该条目被修改如下:

A1<int> a1( /* args */ );
myvect v(a1)
swap( mapInstance[0],v );

然后,矢量交换,具体取决于std :: allocator_traits< A1< int>> :: propagate_on_container_swap :: value的值

现在,如果A是std :: scoped_allocator_adaptor< A1< std :: pair< const int,myvect>>>事情变得更有趣! scoped_allocator_adaptor,顾名思义,是一个适配器,它允许任何分配器类型与Scoped Allocator Model一起使用,这意味着容器的分配器可以传递给容器的子节点,子节点传递给子节点的子节点等等.因为这些类型使用分配器并且可以用它们构造.)

默认情况下,容器和分配器不使用作用域分配器模型,您需要使用scoped_allocator_adaptor(或编写自己的分配器类型,使用它). (而C 03对于作用域分配器完全没有支持.)

如果该条目是这样创建的:

mapInstance[0];

然后,scoped_allocator_adaptor将使用map的allocator的副本构造它,而不是默认构造的条目,因此该条目将构造为myvect(A1< int>(mapInstance.get_allocator())).

如果该条目是这样创建的:

A1<int> a1( /* args */ );
myvect v(a1)
mapInstance.insert(mymap::value_type(0,v));

然后该条目将具有v的数据的副本,但不会使用其分配器,而是由scoped_allocator_adaptor传递分配器,因此将构造为:myvect(v,A1< int>(mapInstance.get_allocator()) ).

如果这有点令人困惑,欢迎来到我的世界,但不要担心,在你的情况下矢量< int>将始终使用std :: allocator< int>.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读