为什么他们在 STL 的分配器和向量类中使用指针、void_pointer和其他 typedef?

Why do they use pointer, void_pointer and other typedef inside allocator and vector classes of STL?

提问人:graveman 提问时间:9/17/2023 最后编辑:alfCgraveman 更新时间:9/17/2023 访问量:75

问:

https://en.cppreference.com/w/cpp/memory/allocator

value_type是 的 typedef(或别名) ,T

pointer是 的 typedef(或别名) ,T*

void_pointer是 的 typedef(或别名) ,void*

从STL开发人员的角度来看,为什么我们需要这个? 不总是指针吗? 不总是指向无效的指针吗? 请给我一些解释或链接。 我真的不明白这一点。T*void*

C++ STL 嵌套类型

评论

1赞 273K 9/17/2023
看看地图或unordered_map容器,他们会回答你的问题。
1赞 n. m. could be an AI 9/17/2023
这个想法是 STL 容器可以将其数据存储在无法通过常规指针访问的内存中。想想 NUMA,或者想想旧的 x86 内存模型及其近指针和远指针。
1赞 alfC 9/17/2023
有些非 STL 分配器可以返回非普通指针的内容,请参阅 Thrust 分配器或 Boost.Interprocess 分配器。
1赞 BoP 9/17/2023
在 C++ 十几岁的时候,我们的系统具有分段内存,具有“近指针”(在段内)和“远指针”(段之间)。当时,并不是唯一的选择。请注意,它显示“(在 C++20 中删除)”,因为不再需要它。T*
1赞 n. m. could be an AI 9/17/2023
@BoP 它们仅从 std::allocator 中删除。用户提供的分配器可以定义它们,并且它们仍然像以前一样运行,请参阅 en.cppreference.com/w/cpp/memory/allocator_traits

答:

4赞 user17732522 9/17/2023 #1

std::allocator只是 Allocator 概念的一种可能实现。标准库中有更多的分配器类型,用户可以编写自己的类型,以满足分配器概念和分配器感知标准库类型,例如也可以与这些分配器一起使用。std::vectorstd::allocator

分配器概念需要这些 typedef,因为不需要此类分配器实现用作 void 指针或指针类型。正如您在上面链接的页面上所看到的,它们只需要满足一些概念,例如 NullablePointer,使它们的行为类似于本机原始指针。void*value_type*

这个想法是,您可以使用所谓的花哨指针实现分配器,这些指针具有与本机原始指针不同的功能。此类指针类型的一个示例是 boost::interprocess::offset_ptr,它是一种类似指针的类型,指向自身的偏移量而不是绝对地址。如果要将容器存储在进程之间共享的内存中,这将非常有用。由于每个进程都将共享内存页映射到其各自地址空间中的不同基虚拟地址,因此绝对本机指针不能同时引用所有进程中的预期位置。

从技术上讲,由于 Allocator 的每个用户都应该通过 std::allocator_traits 接口访问它,该接口为这些 typedef 提供默认值,因此如果您想要列出的默认值,通常不需要在 Allocator 类型本身中实际声明它们。(没有默认值且必须始终声明的除外。value_type

但是,仅在 C++11 中添加并且一直存在。因此,删除 typedefs 是一个不兼容的更改。因此,它们仅在 C++17 中被弃用,并在 C++20 中删除(除了 )。std::allocator_traitsstd::allocatorstd::allocatorvalue_type

评论

0赞 graveman 9/19/2023
多谢!非常感谢!它解释了很多。