如何用std::ranges::set_difference同步不同值类型的std::map?
使用std::ranges::set_difference同步两个值类型不同的std::map
可行性说明
完全可以通过std::ranges::set_difference实现需求。因为std::map默认按键升序排列,满足set_difference要求的输入范围必须有序的前提条件。只需通过投影操作让算法基于两个map的键进行比较,同时保留原容器的元素类型输出即可。
具体实现代码
1. 定义键投影函数
先定义一个投影lambda,用于从map的键值对中提取键,供算法比较使用:
auto key_proj = [](const auto& pair) { return pair.first; };
2. 找出需要释放的资源(仅存在于allocatedResources的项)
std::vector<std::pair<unsigned, Resource*>> resourcesNoLongerNeeded; std::ranges::set_difference( allocatedResources, resourcePrototypes, std::back_inserter(resourcesNoLongerNeeded), {}, // 默认使用std::less<unsigned>,与map的排序规则一致 key_proj, // 提取allocatedResources的键作为比较依据 key_proj // 提取resourcePrototypes的键作为比较依据 );
3. 找出需要分配资源的原型(仅存在于resourcePrototypes的项)
交换两个输入范围即可得到反向差集:
std::vector<std::pair<unsigned, Prototype*>> prototypesToAllocateAsResources; std::ranges::set_difference( resourcePrototypes, allocatedResources, std::back_inserter(prototypesToAllocateAsResources), {}, key_proj, key_proj );
4. 执行资源同步操作
// 释放不再需要的资源并从allocatedResources中移除 for (const auto& [id, res] : resourcesNoLongerNeeded) { delete res; allocatedResources.erase(id); } // 根据原型分配新资源并加入allocatedResources for (const auto& [id, proto] : prototypesToAllocateAsResources) { Resource* new_resource = proto->createResource(); // 假设Prototype类提供创建Resource的方法 allocatedResources.emplace(id, new_resource); }
常见编译失败原因排查
之前编译不通过大概率是以下原因之一:
- 未正确指定投影参数:
std::ranges::set_difference的投影参数是第5、6个参数,遗漏或类型不匹配会触发编译错误。 - 投影lambda未处理const:
std::map的元素是const std::pair<const unsigned, T*>,投影函数必须能接受const引用类型的键值对。 - 输出容器元素类型不匹配:比如尝试将
resourcePrototypes的元素输出到Resource*类型容器中,类型不兼容会导致编译失败。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

