cppreference中的选择报价:
这种运行时多态性使使用polymorphic_allocator的对象的行为就像在运行时使用了不同的分配器类型一样,尽管静态分配器类型相同
“常规”分配器的问题在于它们会更改容器的类型。如果你想要一个vector
使用特定的分配器,则可以使用Allocator
template参数:
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
多态分配器是具有成员的单个分配器类型,该成员可以通过动态分配而不是通过模板机制来定义分配器行为。这使您可以拥有使用特定的,自定义分配的容器,但是它们仍然是普通类型的。
分配器行为的自定义是通过给分配器a来完成的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指针的存储开销(很可能可以忽略不计)以及为分配分配虚拟函数的开销。实际上,主要问题可能是与不使用多态分配器的旧代码缺乏兼容性。
allocator<T>
固有的一些问题 。因此,如果经常使用分配器,您将看到其中的价值。