如何用指针指向C++中map<int,order>与map<int,order,greater<>>容器
解决不同比较器map的统一遍历更新问题
你的代码编译失败的核心原因是:map<int, order>(默认用std::less<int>排序)和map<int, order, greater<>>(用std::greater<int>排序)是完全不同的C++类型,模板参数的差异导致它们的指针类型不兼容,无法用同一个map<int, order>*指针指向两种容器。
下面给出两种可行的解决方案:
方案一:模板函数适配任意map类型
把更新逻辑封装成模板函数,让它能接受任意符合键为int、值为order的map类型,这样不管是升序还是降序map都能复用同一套逻辑。
修改后的完整代码:
#include <iostream> #include <map> using namespace std; struct order { int qty; int sum; }; // 模板函数,适配任意键为int、值为order的map类型 template <typename MapType> void updateOpr(MapType* pmap) { order* pre = nullptr; for (auto& [key, value] : *pmap) { if (pre == nullptr) { value.sum = value.qty; } else { value.sum = pre->sum + value.qty; } pre = &value; } } int main() { map<int, order, greater<>> imap1; // 降序map map<int, order> imap2; // 升序map bool flag = true; // 填充测试数据 imap1[1] = {10, 0}; imap1[2] = {20, 0}; imap1[3] = {30, 0}; imap2[1] = {10, 0}; imap2[2] = {20, 0}; imap2[3] = {30, 0}; int key = 10; if (flag) { // 处理降序map的逻辑 if (imap1.contains(key)) { // todo: 自定义逻辑 } updateOpr(&imap1); // 打印验证结果(降序遍历:3→2→1,sum分别为30、50、60) for (auto& [k, v] : imap1) { cout << "降序map: key=" << k << ", sum=" << v.sum << endl; } } else { // 处理升序map的逻辑 if (imap2.contains(key)) { // todo: 自定义逻辑 } updateOpr(&imap2); // 打印验证结果(升序遍历:1→2→3,sum分别为10、30、60) for (auto& [k, v] : imap2) { cout << "升序map: key=" << k << ", sum=" << v.sum << endl; } } return 0; }
方案二:用std::variant统一管理不同类型的map指针
如果需要一个“统一的容器”来存储两种map的指针,避免重复写if-else分支,可以用C++17引入的std::variant,配合std::visit执行统一逻辑:
#include <iostream> #include <map> #include <variant> using namespace std; struct order { int qty; int sum; }; template <typename MapType> void updateOpr(MapType* pmap) { order* pre = nullptr; for (auto& [key, value] : *pmap) { if (pre == nullptr) { value.sum = value.qty; } else { value.sum = pre->sum + value.qty; } pre = &value; } } int main() { map<int, order, greater<>> imap1; map<int, order> imap2; bool flag = true; imap1[1] = {10, 0}; imap1[2] = {20, 0}; imap1[3] = {30, 0}; imap2[1] = {10, 0}; imap2[2] = {20, 0}; imap2[3] = {30, 0}; // 定义variant类型,包含两种map的指针类型 using MapPtrVariant = variant<map<int, order, greater<>>*, map<int, order>*>; MapPtrVariant pmap = flag ? static_cast<MapPtrVariant>(&imap1) : static_cast<MapPtrVariant>(&imap2); int key = 10; // 用std::visit遍历variant,执行统一逻辑 visit([key](auto* map_ptr) { if (map_ptr->contains(key)) { // todo: 自定义逻辑 } updateOpr(map_ptr); // 打印结果 const string& order_type = is_same_v<decltype(*map_ptr), map<int, order>> ? "升序" : "降序"; for (auto& [k, v] : *map_ptr) { cout << order_type << "map: key=" << k << ", sum=" << v.sum << endl; } }, pmap); return 0; }
关键说明
- 模板函数是最直接的解决方案,它让更新逻辑与map的排序规则(比较器)完全解耦,只要map的键值类型匹配就能复用。
std::variant适合需要统一管理多种类型指针的场景,避免大量重复的if-else分支代码。
内容的提问来源于stack exchange,提问作者seacat
相关产品推荐
相关产品推荐

