You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带polymorphic_allocator的嵌套pmr vector无法用emplace_back构造的原因

嵌套pmr vector调用emplace_back触发static_assert失败的原因

先看这段会报错的代码:

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

运行后触发断言错误:

static assertion failed: construction with an allocator must be possible if uses_allocator is true

但以下几种类似场景都能正常运行:

场景1:先构造内层vector再push_back

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));

场景2:内层是非pmr vector时调用emplace_back

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

场景3:外层是非pmr vector时调用emplace_back

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

核心原因解析

问题出在pmr容器的allocator传播规则和emplace_back的参数处理逻辑上:

  1. pmr容器的uses_allocator特性:
    std::pmr::vector本质是std::vector<T, std::pmr::polymorphic_allocator<T>>的别名。对于外层的pmr::vector<pmr::vector<int>>,其分配器是polymorphic_allocator<pmr::vector<int>>。根据C++标准的std::uses_allocator规则,pmr::vector<int>满足uses_allocator_v<pmr::vector<int>, polymorphic_allocator<...>> == true——因为它本身就是基于polymorphic_allocator实现的容器。

  2. emplace_back的参数传递逻辑:
    当外层pmr容器调用emplace_back时,会自动尝试将自身的分配器传递给内层元素的构造函数。此时你传入了一个memory_resource*作为构造参数,容器会尝试用「外层分配器 + 传入的memory_resource*」来构造内层pmr::vector<int>,但内层pmr::vector<int>并没有这样的构造函数:它要么接受单个memory_resource*,要么接受单个polymorphic_allocator<T>,但不支持两者同时作为参数,这直接触发了断言检查。

  3. 对比场景的差异:

    • 场景1:push_back是移动已构造完成的内层vector,外层容器不需要参与内层的构造过程,自然不会传递分配器,因此无冲突。
    • 场景2:内层是普通std::vector<int>,它可以接受polymorphic_allocator作为构造参数(符合uses_allocator的要求),所以外层传递分配器后能正常构造。
    • 场景3:外层是普通std::vector,其分配器是std::allocator,而uses_allocator_v<pmr::vector<int>, std::allocator<int>> == false,因此外层容器不会传递自身的分配器,直接用你传入的memory_resource*构造内层pmr vector,没有问题。

内容的提问来源于stack exchange,提问作者Zereges

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:31:02