C++中向std::map<double,pair<int,int>>插入元素及遍历打印问题
问题根因
你遇到的报错核心是C++最令人头疼的解析(Most Vexing Parse)规则:你写的std::map<double, pair<int, int>> m (); 并不会被编译器识别为定义一个名为m的map对象,而是会被解析为声明一个返回值为std::map<double, pair<int, int>>类型、无入参的函数m,所以后续调用m.insert、m.begin的时候编译器会提示m不是类类型。
第一步:修复map声明
两种写法二选一即可:
- 直接去掉括号走默认构造:
std::map<double, std::pair<int, int>> m;
- C++11及以后版本可以用统一初始化花括号,彻底避免解析歧义:
std::map<double, std::pair<int, int>> m{};
第二步:修复插入逻辑
这里还有一个隐藏坑:如果x和y都是int类型,直接执行x/y会触发整数除法,只会得到整数结果,不会得到你要的浮点分数值,需要先做类型转换:
// 先转成double再做除法,避免整数除法截断 double score = static_cast<double>(x) / y; m.insert(std::make_pair(score, std::make_pair(x, y)));
第三步:修复遍历打印逻辑
std::pair<int, int>没有默认的<<运算符重载,不能直接传给cout输出,需要分别取出pair的first(分子)和second(分母)打印:
// 迭代器写法 for (auto it1 = m.begin(); it1 != m.end(); ++it1) { std::cout << it1->first << "->" << it1->second.first << "/" << it1->second.second << std::endl; } // C++11及以后也可以用范围for简化写法 for (const auto& item : m) { std::cout << item.first << "->" << item.second.first << "/" << item.second.second << std::endl; }
额外注意事项
不推荐用double作为map的key:浮点数存在精度误差,两个数学上相等的分数,可能因为计算过程中的精度损失被识别为不同的key。如果需要严格判等,建议先将分数约分为最简形式,直接用std::pair<int, int>(约分后的分子、分母)作为key,避免精度问题。
内容的提问来源于stack exchange,提问作者Simona
相关产品推荐
相关产品推荐

