Kem*_*mal 8 c++ memory-management std allocator c++11
据我所知,std::scoped_allocator_adapter
提供了一种控制机制,用于分别指定容器,元素,元素元素等使用哪个分配器,假设元素本身是容器.
也就是说,我无法理解语义std::scoped_allocator_adapter
.
Bjarne Stroustrup在"C++编程语言 "第34.4.4节中提供了以下4个例子.1001(我将在我的问题中将它们称为示例-1,示例-2等.):
我们有四种方法来分配字符串向量:
Run Code Online (Sandbox Code Playgroud)// vector and string use their own (the default) allocator: using svec0 = vector<string>; svec0 v0; // vector (only) uses My_alloc and string uses its own allocator (the default): using Svec1 = vector<string,My_alloc<string>>; Svec1 v1 {My_alloc<string>{my_arena1}}; // vector and string use My_alloc (as above): using Xstring = basic_string<char,char_traits<char>, My_alloc<char>>; using Svec2 = vector<Xstring,scoped_allocator_adaptor<My_alloc<Xstring>>>; Svec2 v2 {scoped_allocator_adaptor<My_alloc<Xstring>>{my_arena1}}; // vector uses its own alloctor (the default) and string uses My_alloc: using Xstring2 = basic_string<char, char_traits<char>, My_alloc<char>>; using Svec3 = vector<xstring2,scoped_allocator_adaptor<My_alloc<xstring>,My_alloc<char>>>; Svec3 v3 {scoped_allocator_adaptor<My_alloc<xstring2>,My_alloc<char>>{my_arena1}};
为了完整起见,My_alloc
书中定义如下:
template<typename T>
struct My_alloc { // use an Arena to allocate and deallocate bytes
Arena& a;
My_alloc(Arena& aa) : a(aa) { }
My_alloc() {}
// usual allocator stuff
};
Run Code Online (Sandbox Code Playgroud)
现在,关于我的问题:
问题1:在实施例-3,莫非元件的Svec2
使用My_alloc<char>{my_arena1}
,以用于(的类型及其元素分配存储char
)?
问题2:如果是这样,它是否与在其定义中Xstring
使用自定义分配器的事实有关My_alloc<char>
?IOW,即使Xstring
是用另一个分配器规定,不会对元素的Svec_2
仍使用My_alloc<char>{my_arena1}
以来scoped_allocator_adaptor
的Svec2_
支配用于所做的分配,其分配Svec_2
和分配由它的元素(类型做Xstring
)?
问题3:考虑下面的代码,该代码应该是Example-3的变体.难道v2_
(类型的元素std::string
在这种情况下)使用My_alloc<char>{my_arena1}
?如果没有,他们使用哪个分配器?
// both v2_ and its elements to use My_alloc<some_type>{my_arena1}
using Svec2_ =
vector<string, scoped_allocator_adaptor<My_alloc<string>>> // value_type std::string, instead of Xstring
Svec2_ v2_ {scoped_allocator_adaptor<My_alloc<string>>{my_arena1}};
Run Code Online (Sandbox Code Playgroud)
问题4:基于对www.cppreference.com下面我引用的解释,在我看来,在例-4 ,Svec3
并没有使用其默认分配std::allocator
给它的元素(的分配存储Xstring2
类型),而是"外分配器",这是My_alloc<xstring>
.元件的Svec3
,在另一方面,将使用MyAlloc<char>
这就是"内分配器".(而不是因为它是在定义中指定的分配Xstring2
,而是因为它是"内部分配"中scoped_allocator_adapter
的Svec3
.)
这就是它在www.cppreference.com std::scoped_allocator_adaptor
节中所说的内容:
鉴于:
Run Code Online (Sandbox Code Playgroud)template< class OuterAlloc, class... InnerAlloc > class scoped_allocator_adaptor : public OuterAlloc;
直接使用scoped_allocator_adaptor构造的容器
OuterAlloc
用于分配其元素,但如果元素本身是容器,则它使用第一个内部分配器.所述元件该容器的,如果它们本身的容器中,使用第二内分配器等,如果有更多的水平到所述容器之外还有内分配器,所述最后内分配器再用于 所有进一步嵌套的容器.
基于此,不应该正确的例子如下?
// v3_ uses its default allocator(or rather std::allocator), while its elements use My_alloc
using Xstring2 = basic_string<char, char_traits<char>, My_alloc<char>>;
using Svec3_ =
vector<Xstring2, scoped_allocator_adaptor<std::allocator<Xstring2>, My_alloc<char>>>;
Svec3_ v3_ {
scoped_allocator_adaptor<std::allocator<Xstring2>, My_alloc<char>>{my_arena1}
};
Run Code Online (Sandbox Code Playgroud)
这样一来,没有这个使用scoped_allocator_adaptor
听写,通过分配Svec3_
使用std::allocator
,而它的元素使用My_alloc<char>{my_arena1}
他们的分配?
我可以告诉我对scoped allocator模型有根本的误解.有人能指出我错过了什么吗?
长话短说
问题 1:
是的。
问题 2:
不。
问题 3:
否。使用
其默认分配器 (= )。std::allocator<char>()
问题 4:
你是对的。
(但是示例 4 及其修改版本都无法编译,因为它们缺少外部分配器的构造函数参数。)
有人可以指出我缺少什么吗?:
我不认为您误解了某些内容,而是您只是忘记了My_alloc
不能用于std::string
因为分配器类型std::string
是std::allocator
,而不是My_alloc
。
请记住,分配器仅用于构造函数参数,因此不能使用具有不同类型的分配器。
正如 Jonathan Wakely 指出的那样,当Svec2
orSvec2_
创建它的元素时,它会调用:
std::allocator_traits<std::scoped_allocator_adaptor<My_alloc<xxx>>>::construct(
get_allocator(), void_ptr, args...
);
Run Code Online (Sandbox Code Playgroud)
其中xxx
是Xstring2
forSvec2
或std::string
for Svec2_
。
它调用get_allocator().construct(void_ptr, args...)
,然后调用以下任意一项:
std::allocator_traits<My_alloc<xxx>>::construct(
outer_allocator(), void_ptr, std::allocator_tag, inner_allocator(), args...
);
Run Code Online (Sandbox Code Playgroud)
构造函数xxx(std::allocator_tag, inner_allocator(), args...)
调用是否格式正确。
或者
std::allocator_traits<My_alloc<xxx>>::construct(
outer_allocator(), void_ptr, args..., inner_allocator()
);
Run Code Online (Sandbox Code Playgroud)
构造函数xxx(args..., inner_allocator())
调用是否格式正确。
或者
std::allocator_traits<My_alloc<xxx>>::construct(
outer_allocator(), void_ptr, args...
);
Run Code Online (Sandbox Code Playgroud)
构造函数xxx(args...)
调用是否格式正确。
在这些示例中, 和outer_allocator()
都inner_allocator()
具有类型My_alloc<xxx>
。
所有std::basic_string
分配器感知容器都具有构造函数,其最后一个参数是所有构造函数重载的分配器。
所以,如果inner_allocator()
(类型My_alloc<xxx>
) 可转换为元素的分配器类型,则调用第二种形式(即使用分配器);否则调用第三种形式(即从不使用分配器)。
对于Xstring2
,分配器类型为My_alloc<char>
,并且My_alloc<Xstring2>
可转换为My_alloc<char>
。因此, 的元素Svec2
由 构造Xstring2(args..., inner_allocator())
,然后它们的内部存储器由 分配My_alloc<char>
。
相比之下, 的分配器类型std::string
是std::allocator<char>
, 并且My_alloc<Xstring2>
不能转换为std::allocator<char>
。因此, 的元素Svec2_
由 构造std::string(args...)
,然后它们的内部内存由默认分配器 (= ) 分配std::allocator<char>()
。
FYI:严格来说,取决于std::uses_allocator
是否使用第三种形式。
归档时间: |
|
查看次数: |
352 次 |
最近记录: |