C++11 std::map插入与upper_bound调用报错问题求助
解决C++11 std::map复杂嵌套键的编译错误与查找需求
一、编译错误核心原因排查
std::map要求键类型必须支持严格弱序比较,你的键类型std::pair<int, std::pair<long long int, long int>>本身符合默认比较规则(std::pair会按顺序逐元素比较),编译报错大概率是调用insert()或upper_bound()时参数不匹配:
1. insert() 调用修正
如果是构造临时键值对时语法错误,按以下方式编写即可:
#include <map> #include <utility> // 先定义类型别名提升可读性 using KeyType = std::pair<int, std::pair<long long int, long int>>; using ValueType = std::pair<...>; // 替换成你的嵌套pair值类型 std::map<KeyType, ValueType> loopMap; // 方式1:用make_pair插入 loopMap.insert(std::make_pair( KeyType(1, std::make_pair(123456789LL, 98765L)), ValueType(...) // 传入你的值结构 )); // 方式2:用emplace高效构造(C++11支持) loopMap.emplace( std::piecewise_construct, std::forward_as_tuple(1, std::make_pair(123456789LL, 98765L)), std::forward_as_tuple(...) // 传入值的构造参数 );
2. upper_bound() 调用修正
upper_bound必须传入完整的键类型参数,若要查找首元素为某int的键的上界,需构造对应上限键:
#include <climits> // 查找首元素为5的所有键的上界 auto it = loopMap.upper_bound(KeyType(5, std::make_pair(LLONG_MAX, LONG_MAX)));
用LLONG_MAX和LONG_MAX确保第二个pair元素取最大值,让upper_bound定位到所有首元素为5的键的末尾之后。
二、优化:贴合"通过int查找long int"的结构
原嵌套键结构可读性差且查找不便,推荐两种更适配需求的方案:
方案1:用二级map/vector存储关联数据
把int作为一级键,对应的值存储所有关联的(long long, long)对,直接通过int定位后遍历即可:
#include <map> #include <vector> #include <utility> std::map<int, std::vector<std::pair<long long int, long int>>> intToPairs; // 插入数据示例 int counter = 1; long long llVal = 123456789LL; long lVal = 98765L; intToPairs[counter].emplace_back(llVal, lVal); // 通过int查找对应long int int targetInt = 1; auto it = intToPairs.find(targetInt); if (it != intToPairs.end()) { for (const auto& p : it->second) { long targetLong = p.second; // 处理你的业务逻辑 } }
该方案完全避开复杂嵌套键的问题,可读性和维护性拉满,C++11原生支持。
方案2:自定义比较器实现前缀查找(保留原结构)
若必须沿用原嵌套键结构,可自定义比较器让map优先按int排序,再用equal_range直接获取同一int对应的所有键值对:
#include <map> #include <utility> #include <climits> struct KeyCompare { bool operator()(const std::pair<int, std::pair<long long, long>>& a, const std::pair<int, std::pair<long long, long>>& b) const { // 优先比较int首元素,再比较后续pair if (a.first != b.first) { return a.first < b.first; } return a.second < b.second; } }; // 用自定义比较器声明map using KeyType = std::pair<int, std::pair<long long int, long int>>; using ValueType = std::pair<...>; std::map<KeyType, ValueType, KeyCompare> loopMap; // 查找所有首元素为targetInt的键值对 int targetInt = 1; KeyType lowerKey(targetInt, std::make_pair(LLONG_MIN, LONG_MIN)); KeyType upperKey(targetInt + 1, std::make_pair(LLONG_MIN, LONG_MIN)); auto range = loopMap.equal_range(lowerKey, upperKey); for (auto it = range.first; it != range.second; ++it) { long targetLong = it->first.second.second; // 处理逻辑 }
三、关于operator[]的替代方案
operator[]会默认构造值类型,若你的值是无默认构造的嵌套pair,必然报错。此时用emplace或insert+std::make_pair是更稳妥的选择,正如前面示例中的写法。
内容的提问来源于stack exchange,提问作者CikoXp
相关产品推荐
相关产品推荐

