标准库分配器指针类型的要求

发布于 2024-10-27 01:36:24 字数 1375 浏览 0 评论 0原文

我正在尝试编写一个四叉树稀疏矩阵类。简而言之,quadtree_matrixquadtree_matrix 的零矩阵或四元(ne, nw, se, sw) >。

我最终想测试不同的分配方案,因为这可能会影响线性代数运算的性能。因此,我还将在标准分配器类型上模板化quadtree_matrix,以便我可以重用现有的分配器。

我必须分配两种不同类型的数据:Tnode,其中包含四个指针(指向 T 或节点)。对于我将考虑的所有算法,我确信会得到什么样的数据,因为我知道在算法的任何点所面临的子矩阵的大小是多少(我什至不需要存储这些大小)。

我当然会使用两个不同的分配器:这是可以的,因为分配器类型提供了重新绑定模板和模板复制构造函数(并且旨在用作值类型,如 get_allocator 标准容器的成员建议返回一个副本)。

问题在于分配器成员函数使用某种指针类型,该类型不需要是普通指针。一些分配器(增强进程间分配器)广泛使用此功能。

如果分配器指针类型是花园品种指针,我不会有任何问题:至少,我可以使用指向 void 的指针并将它们重新转换为正确的类型(node*T *)。我也可以使用工会(可能更好)。

据我所知,对 allocator::pointer 类型的 PODness 没有要求。它们只需要是随机访问迭代器。

现在,我的问题是:

给定一个分配器类模板 A (或其等效的 A::rebind::other),是否存在任何保证:

  1. 能够将 A::pointer 静态转换为 A::pointer(提供 U)T 的可访问基础吗?
  2. 能够将 A::pointer 静态转换为 A< U>::pointer 提供的 TU 的可访问基础,并且castee的“运行时类型”(无论这在上下文中意味着什么)是< code>U ?
  3. 类型 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:

  1. The ability to static cast A<T>::pointer to A<U>::pointer provided U is an accessible base of T ?
  2. The ability to static cast A<T>::pointer to A<U>::pointer provided T is an accessible base of U and the "runtime type" (whatever this means in this context) of the castee is U ?
  3. The type A<void>::pointer (if this makes sense) ?

Or is there a solution to my problem I didn't think about ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

盛夏尉蓝 2024-11-03 01:36:24

从 20.1.5/2 的表中可以清楚地看出 A::pointer 的类型必须是“指向 T 的指针”。由于这些指针类型通常是可转换的,所以 1 和 2 是正确的。那么A::pointer 必须是void*

编辑:
20.1.5/4 中也有明确的措辞(它适用于标准容器对分配器的假设):

typedef 成员指针,
const_pointer、size_type 和
Difference_type 必须是
T*、T const*、size_t 和 ptrdiff_t,
分别。

From the tables in 20.1.5/2 it clearly indicates that the type of A<T>::pointer must be "pointer to T". Since those pointer types are normally convertible your 1 and 2 are true. It follows then that A<void>::pointer must be void*.

EDIT:
There's also explicit wording in 20.1.5/4 (it applies to what standard containers may assume about allocators):

The typedef members pointer,
const_pointer, size_type, and
difference_type are required to be
T*,T const*, size_t, and ptrdiff_t,
respectively.

黯然#的苍凉 2024-11-03 01:36:24

不,不是真的。

要求 A::pointer 可转换为 A::const_pointer 和 A::void_pointer 但这就是我能找到的全部。

::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.

萌无敌 2024-11-03 01:36:24

请注意,即使 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:

  • Write a small smart pointer that use a given allocator to perform the destruction (instead of delete)
  • Use boost::variant on your pointers

This way you have both automatic memory management and compacity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文