为Boost cpp_dec_float_100指定分配器后lower_bound比较报错如何解决
问题原因
错误的核心是Mult_t类型别名的分配器参数传递错误,导致生成的数值类型没有正确实现operator<重载,STL算法std::lower_bound内部的比较操作无法匹配有效运算符。
你当前的写法把number类型的分配器传给了cpp_dec_float后端的分配器参数,两个模板参数的预期类型完全不匹配:
boost::multiprecision::cpp_dec_float的第三个模板参数是后端存储十进制数位所用的分配器,预期是针对普通POD类型(如char、unsigned int)的分配器- 你传入的是
allocator<boost::multiprecision::number<...>>,是针对完整浮点数值类型的分配器,不符合后端参数要求
这就导致最终生成的类型是残缺的,解引用迭代器拿到的是底层未封装的后端类型,没有对应比较运算符,直接触发编译错误。
修复方案
1. 修正Mult_t类型定义
正确的带自定义分配器的100位十进制浮点数定义如下:
#include <boost/multiprecision/cpp_dec_float.hpp> #include <vector> #include <algorithm> #include <cmath> // 首先定义带分配器的cpp_dec_float后端,第三个参数传POD类型分配器 using FloatBackend = boost::multiprecision::cpp_dec_float<100, int, std::allocator<char>>; // 封装为完整的number类型,可选关闭表达式模板避免STL算法适配问题 using Mult_t = boost::multiprecision::number<FloatBackend, boost::multiprecision::et_off>;
如果你有自定义分配器需求,把std::allocator<char>替换为你指定的泛型分配器即可。
2. 优化二分查找函数适配
为避免STL算法自动推导类型出错,显式指定比较规则,同时明确调用boost提供的abs实现:
std::vector<Mult_t>::iterator search(std::vector<Mult_t> &vec, Mult_t value){ // 显式传入比较lambda,确保用Mult_t的重载运算符 auto it = std::lower_bound(vec.begin(), vec.end(), value, [](const Mult_t& a, const Mult_t& b){ return a < b; }); if(it != vec.begin()){ // 明确调用boost的abs,避免ADL查找匹配到std::abs if(boost::multiprecision::abs(value - *(it - 1)) < boost::multiprecision::abs(value - *it)){ --it; } } return it; }
额外注意事项
- 如果你使用CERN ROOT读取数据,需要确保ROOT的反序列化逻辑能正确识别你定义的
Mult_t类型的内存布局,修正类型定义后原来的内存占用优化效果依然保留 - 关闭表达式模板(
et_off)会牺牲少量运算性能,但可以完全避免STL算法、算术运算中临时表达式的类型不匹配问题,兼容性更好
内容的提问来源于stack exchange,提问作者10GeV
相关产品推荐
相关产品推荐

