使用Boost多态分配器时,std::unordered_map存std::pair编译失败问题
问题解答
1. 根本原因解释
问题出在Boost容器库的分配器适配逻辑与标准库std::pair的兼容性差异上:
- 当
std::unordered_map使用boost::container::pmr::polymorphic_allocator时,调用emplace/try_emplace构造std::pair类型的Value会触发Boost内部的dispatch_uses_allocator函数,用于处理分配器的传递逻辑。 - Boost的
dispatch_uses_allocator对std::pair设有特殊分支处理,但当前场景下,std::pair与boost::pmr::polymorphic_allocator的组合无法匹配到合适的重载函数——错误信息里的候选函数明确要求T不是pair类型,且Boost的uses_allocatortrait未正确识别std::pair可接受该分配器,最终导致无可用重载匹配。 - 自定义结构体
Buz不属于Boost识别的pair类型,会进入通用的分配器处理分支,因此可以正常编译。而原代码使用标准库std::pmr时,标准库的uses_allocator和适配逻辑对std::pair的处理符合预期,所以没有问题。
2. 修复方案
方案一:特化Boost的uses_allocator trait
在代码开头(使用std::pair作为Value之前)添加特化,明确告知Booststd::pair可以接受polymorphic_allocator:
#include <utility> namespace boost::container { template <typename T1, typename T2, typename Alloc> struct uses_allocator<std::pair<T1, T2>, Alloc> : std::true_type {}; }
该特化会让Boost的分配器适配逻辑正确处理std::pair,匹配到对应的dispatch_uses_allocator重载。
方案二:替换std::pair为自定义结构体
沿用示例中的Buz这类自定义结构体替代std::pair作为Value类型,绕开Boost对std::pair的特殊处理逻辑,无需修改Boost的trait定义。
方案三:使用Boost原生的boost::container::pair
将std::pair替换为Boost容器库自带的boost::container::pair,其与Boost分配器体系原生兼容,不会触发兼容性问题:
// 替换原Value定义 using Value = boost::container::pair<Key, foo::wstring>;
内容的提问来源于stack exchange,提问作者Marek R
相关产品推荐
相关产品推荐

