polymorphic_allocator:何时以及为什么要使用它?

新手上路,请多包涵

是有关 cppreference 的文档, 是工作草案。

我必须承认,我不明白 polymorphic_allocator 的真正目的是什么,以及何时/为什么/如何使用它。

例如, pmr::vector 具有以下签名:

 namespace pmr {
    template <class T>
    using vector = std::vector<T, polymorphic_allocator<T>>;
}

polymorphic_allocator 提供什么?就老式的 std::vector 而言, std::pmr::vector 还提供什么?我现在能做什么,而我直到现在都做不到?

该分配器的真正目的是什么,我应该什么时候实际使用它?

原文由 skypjack 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

来自 cppreference 的选择报价:

这种运行时多态性允许使用 polymorphic_allocator 的对象的行为就像它们在运行时使用不同的分配器类型一样,尽管它们具有相同的静态分配器类型

“常规”分配器的问题在于它们改变了容器的类型。如果你想要一个带有特定分配器的 vector ,你可以使用 Allocator 模板参数:

 auto my_vector = std::vector<int,my_allocator>();

现在的问题是该向量与具有不同分配器的向量的类型不同。例如,您不能将它传递给需要默认分配器向量的函数,或者将具有不同分配器类型的两个向量分配给相同的变量/指针,例如:

 auto my_vector = std::vector<int,my_allocator>();
auto my_vector2 = std::vector<int,other_allocator>();
auto vec = my_vector; // ok
vec = my_vector2; // error

多态分配器是一个单一的分配器类型,其成员可以通过动态分派而不是通过模板机制来定义分配器的行为。这允许您拥有使用特定、自定义分配但仍属于通用类型的容器。

分配器行为的定制是通过给分配器一个 std::memory_resource * 来完成的:

 // define allocation behaviour via a custom "memory_resource"
class my_memory_resource : public std::pmr::memory_resource { ... };
my_memory_resource mem_res;
auto my_vector = std::pmr::vector<int>(0, &mem_res);

// define a second memory resource
class other_memory_resource : public std::pmr::memory_resource { ... };
other_memory_resource mem_res_other;
auto my_other_vector = std::pmr::vector<int>(0, &mes_res_other);

auto vec = my_vector; // type is std::pmr::vector<int>
vec = my_other_vector; // this is ok -
      // my_vector and my_other_vector have same type

在我看来,剩下的主要问题是 std::pmr:: 容器仍然与使用默认分配器的等效 std:: 容器不兼容。在设计与容器一起使用的界面时,您需要做出一些决定:

  • 传入的容器是否可能需要自定义分配?
  • 如果是这样,我应该添加一个模板参数(以允许任意分配器)还是应该强制使用多态分配器?

模板解决方案允许 任何 分配器,包括多态分配器,但有其他缺点(生成的代码大小、编译时间、代码必须在头文件中公开、进一步“类型污染”的可能性,从而不断将问题推向外部)。另一方面,多态分配器解决方案要求 必须 使用多态分配器。这排除了使用 std:: 使用默认分配器的容器,并且可能对与遗留代码的接口有影响。

与常规分配器相比,多态分配器确实有一些较小的成本,例如 memory_resource 指针的存储开销(这很可能可以忽略不计)和分配的虚函数调度成本。实际上,主要问题可能是与不使用多态分配器的遗留代码缺乏兼容性。

原文由 davmac 发布,翻译遵循 CC BY-SA 4.0 许可协议

polymorphic_allocator 是自定义分配器,因为 std::function 是直接函数调用。

它只是让您在容器中使用分配器,而无需在声明时决定使用哪一个。因此,如果您遇到适合多个分配器的情况,您可以使用 polymorphic_allocator

也许您想隐藏使用哪个分配器来简化您的界面,或者您可能希望能够将其换出以适应不同的运行时情况。

首先,您需要需要分配器的代码,然后您需要能够交换使用哪个分配器,然后再考虑 pmr 向量。

原文由 Yakk - Adam Nevraumont 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题