标准库分配器指针类型的要求
我正在尝试编写一个四叉树稀疏矩阵类。简而言之,quadtree_matrix
是 quadtree_matrix
的零矩阵或四元(ne, nw, se, sw)
>。
我最终想测试不同的分配方案,因为这可能会影响线性代数运算的性能。因此,我还将在标准分配器类型上模板化quadtree_matrix
,以便我可以重用现有的分配器。
我必须分配两种不同类型的数据:T
或 node
,其中包含四个指针(指向 T 或节点)。对于我将考虑的所有算法,我确信会得到什么样的数据,因为我知道在算法的任何点所面临的子矩阵的大小是多少(我什至不需要存储这些大小)。
我当然会使用两个不同的分配器:这是可以的,因为分配器类型提供了重新绑定模板和模板复制构造函数(并且旨在用作值类型,如 get_allocator 标准容器的成员建议返回一个副本)。
问题在于分配器成员函数使用某种指针
类型,该类型不需要是普通指针。一些分配器(增强进程间分配器)广泛使用此功能。
如果分配器指针类型是花园品种指针,我不会有任何问题:至少,我可以使用指向 void 的指针并将它们重新转换为正确的类型(node*
或 T *)。我也可以使用工会(可能更好)。
据我所知,对 allocator::pointer
类型的 PODness 没有要求。它们只需要是随机访问迭代器。
现在,我的问题是:
给定一个分配器类模板 A
(或其等效的 A::rebind
),是否存在任何保证:
- 能够将
A
静态转换为::pointer A::pointer
(提供U)
是T
的可访问基础吗? - 能够将
A
静态转换为::pointer A< U>::pointer
提供的T
是U
的可访问基础,并且castee的“运行时类型”(无论这在上下文中意味着什么)是< code>U ? - 类型
A
(如果这有意义的话)?::pointer
或者有解决我的问题的方法吗我没想过?
I am trying to write a quadtree sparse matrix class. In short, a quadtree_matrix<T>
is either the zero matrix or a quadruple (ne, nw, se, sw)
of quadtree_matrix<T>
.
I'd like eventually to test different allocation schemes since this will probably impact the performance of linear algebra operations. So I will also template quadtree_matrix
on a standard allocator type, so that I can reuse existing allocators.
I will have to allocate two different kind of data: either a T
, or a node
, which contains four pointers (to either T or node). For all the algorithms I will consider, I know for sure what kind of data to expect because I know what are the sizes of the submatrices I am facing at any point of the algorithm (I don't even need to store these sizes).
I will of course be using two different allocators: this is ok, since allocator types provide the rebind
template and a template copy constructor (and are intended to be used as value types, as the get_allocator
members of standard containers suggest by returning a copy).
The problem is that allocator member functions use a certain pointer
type, which is not required to be a vanilla pointer. Some allocators (boost interprocess allocators) use this feature extensively.
If the allocator pointer types were garden variety pointers, I would have no problems: at the very least, I could use pointers to void and reinterpret_cast them to the right type (either node*
or T*
). I could also use a union (probably better).
As far as I know, there is no requirement on the PODness of the allocator::pointer
types. They are only required to be random access iterators.
Now, my question is:
Given an allocator class template A<T>
(or its equivalent A::rebind<T>::other
), is there any guarantee on:
- The ability to static cast
A<T>::pointer
toA<U>::pointer
providedU
is an accessible base ofT
? - The ability to static cast
A<T>::pointer
toA<U>::pointer
providedT
is an accessible base ofU
and the "runtime type" (whatever this means in this context) of the castee isU
? - The type
A<void>::pointer
(if this makes sense) ?
Or is there a solution to my problem I didn't think about ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从 20.1.5/2 的表中可以清楚地看出
A::pointer
的类型必须是“指向T
的指针”。由于这些指针类型通常是可转换的,所以 1 和 2 是正确的。那么A::pointer
必须是void*
。编辑:
20.1.5/4 中也有明确的措辞(它适用于标准容器对分配器的假设):
From the tables in 20.1.5/2 it clearly indicates that the type of
A<T>::pointer
must be "pointer toT
". Since those pointer types are normally convertible your 1 and 2 are true. It follows then thatA<void>::pointer
must bevoid*
.EDIT:
There's also explicit wording in 20.1.5/4 (it applies to what standard containers may assume about allocators):
不,不是真的。
要求 A::pointer 可转换为 A::const_pointer 和 A::void_pointer 但这就是我能找到的全部。
void*
,除非您有一些奇特的特殊内存。No, not really.
There is a requirement that A<T>::pointer is convertible to A<T>::const_pointer and A<T>::void_pointer but that is about all I can find.
A<void>::pointer is likely to be
void*
, unless you have some fancy special memory.请注意,即使
union
可用,我仍然不会使用它,特别是因为在这里您可能会受益于某种形式的自动内存管理(为了使您的包含不泄漏),这需要花哨的课程。因此,我建议采用两步方法:
删除
)这样您就可以同时拥有自动内存管理和容量。
Note that even if a
union
is usable, I would still not use one, especially because here you could probably benefit from some form of automatic memory management (in order for your contain not to leak), which requires fancy classes.I would therefore recommend a two-steps approach:
delete
)boost::variant
on your pointersThis way you have both automatic memory management and compacity.