gpt4 book ai didi

c++ - C++11 有状态分配器是否可以跨类型边界互换?

转载 作者:可可西里 更新时间:2023-11-01 15:24:52 24 4
gpt4 key购买 nike

我的问题基本上是跟进:

How can I write a stateful allocator in C++11, given requirements on copy construction?

基本上,尽管 C++11 标准现在允许有状态分配器,但我们仍然有要求,如果您复制某个 Allocator , 拷贝必须通过 == 比较相等运算符与原件。这表明拷贝可以安全地解除分配由原始分配的内存,反之亦然。

所以,这马上就禁止分配器维护唯一的内部状态,例如平板分配器或内存池等。一种解决方案是使用 shared_ptr内部状态的指向实现惯用语,以便某些原始的所有拷贝Allocator使用相同的底层内存池。那还不错。除了...

根据上面提到的问题以及公认的答案,标准似乎要求 Allocator<T>有一个可互操作的复制构造函数 Allocator<U> ,所以:

Allocator<T> alloc1;
Allocator<U> alloc2(alloc1);
assert(alloc1 == alloc2); // must hold true

换句话说,分配器类型必须可互操作,无论模板参数如何。这意味着如果我使用 Allocator<T> 分配一些内存,我必须能够使用 Allocator<U> 释放该内存从原始 Allocator<T> 构建的实例.

...对于任何尝试编写使用某种基于大小的内存池的分配器的尝试来说,这几乎都是一个阻碍,比如一个 simple_segregated_storage 池,它只返回基于 sizeof(T) 的特定大小的 block 。 .

但是……这是真的吗?

我意识到 Allocator<T>::rebind 需要可互操作的复制构造函数所以容器的用户不需要知道内部细节,比如链表节点类型等等。但据我所知,standard itself似乎没有说什么比要求 Allocator<U> 更严厉的了。由 Allocator<T> 构建必须与原始 Allocator<T> 比较相等实例。

标准基本上需要以下语义,其中 X 是一个类型 Allocator<T> , a1a2X 的实例,Y 是类型Allocator<U> , bAllocator<U> 的实例.

来自:§ 17.6.3.5(分配器要求)

a1 == a2 returns true only if storage allocated from each can be deallocated via the other.

operator == shall be reflexive, symmetric, and transitive, and shall not exit via an exception.

a1 != a2 : same as !(a1 == a2)

a == b : same as a == Y::rebind<T>::other(b)

a != b : same as !(a == b)

X a1(a); Shall not exit via an exception. post: a1 == a

X a(b); Shall not exit via an exception. post: Y(a) == b, a == X(b)


所以,我读这个的方式,Allocator<T> 的实例由 Allocator<U> 构建不一定可以互换。该标准仅要求 a == b必须等同于 Y(a) == b , 不是 a == b必须是 true!

我认为对跨类型边界复制构造函数的要求使这一点变得困惑。但是,按照我的阅读方式,如果我有一个 Allocator<T> , 它必须有一个复制构造函数接受 Allocator<U> ,但这并不暗示:

Allocator<T> alloc1;
Allocator<U> alloc2(alloc1);
assert(alloc2 == alloc1);

换句话说,按照我的理解,上面的断言是允许失败的。但我对我在这里的理解没有信心,因为:

  1. accepted answer to this question另说,回答者是一个有108K声望的人

  2. 标准中复制构造函数要求和相等性要求之间的交互有点困惑,我可能误解了措辞。

那么,我在这里是正确的吗? (顺便说一句, boost::pool_allocator 的实现似乎暗示我是正确的,假设 boost 开发人员关心标准合规性,因为这个分配器不能跨类型边界互换。)

最佳答案

你引用的最后一行:

X a(b); Shall not exit via an exception. post: Y(a) == b, a == X(b)

与你的结论相矛盾。

using X = Allocator<T>;
using Y = Allocator<U>;
Y b;
X a(b);
assert(Y(a) == b);
assert(a == X(b));
// therefore
assert(a == b);

关于c++ - C++11 有状态分配器是否可以跨类型边界互换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27471684/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com