polymorphic_allocator嵌套向量不能通过emplace_back构造



以下代码:

std::pmr::vector<std::pmr::vector<int>> outer_vec(std::pmr::get_default_resource());
outer_vec.emplace_back(std::pmr::get_default_resource());

失败,出现难以想象的错误消息,结尾为

静态断言失败:如果 uses_allocator为 true,则必须可以使用分配器进行构造

向量可以用std::pmr::get_default_resource()参数清楚地构造,例如:

std::pmr::vector<std::pmr::vector<int>> outer_vec(std::pmr::get_default_resource());
std::pmr::vector<int> inner_vec(std::pmr::get_default_resource());
outer_vec.push_back(std::move(inner_vec));

std::pmr::vector可以使用emplace_back来构造元素,例如:

std::pmr::vector<std::vector<int>> outer_vec(std::pmr::get_default_resource());
outer_vec.emplace_back();

为什么两者的结合会失败?什么static_assert失败了?

请注意,如果外部向量不pmr,则它有效:

std::vector<std::pmr::vector<int>> vec;
vec.emplace_back(std::pmr::get_default_resource());

如果构造类型支持,std::pmr::polymorphic_allocator使用使用分配器构造std::vector确实支持用途分配器构造,并且内std::vector的分配器类型与外部分配器的类型兼容。

因此,分配器构造将被外部向量使用。这意味着,每当向量构造一个新元素时,它都会自动将其自己的分配器作为另一个参数传递给元素的构造函数。(具体来说,在这种情况下,get_allocator()->resource()在参数列表的末尾传递。

您正在尝试手动将分配器传递给emplace_back,因此实际上上述两个分配器将传递给内部向量的构造,从而导致失败。

所以,你真正想要的只是outer_vec.emplace_back();.它将外部向量的分配器传播到内部向量。

请注意,outer_vec.push_back(std::move(inner_vec));也会这样做。它还会将外部分配器传播到新的"move"构造的内部向量,从而在必要时将所有元素移动到新的分配中。如果它的分配器与outer_vec的分配器不相等,则它不会使用原始的inner_vec分配。

最新更新