如何在单个std::set中比较结构体的两个属性?
解决std::set中基于结构体双属性(id数组)的查找问题
首先先提一下代码里的小笔误:你定义的比较器类是ComparePager,但std::set的模板参数写的是CompareABC,得把类名统一成CompareABC才能正常编译,我先修正这个问题再讲查找方案。
方案一:利用std::set的有序性快速查找(O(log n)效率)
因为你的std::set已经用CompareABC按照id数组排序了,所以可以直接构造一个包含目标id的临时ABC_PTR,然后调用set::find方法。这个方法利用了set的红黑树结构,查找效率很高。
修正后的完整代码示例:
#include <set> #include <memory> #include <cstring> #include <afxstr.h> // 针对CString的头文件 struct ABC { CString name; byte id[2]; }; typedef std::shared_ptr<ABC> ABC_PTR; // 统一比较器类名,和set的模板参数匹配 class CompareABC { public: bool operator()(const ABC_PTR& m1, const ABC_PTR& m2) const { if (m1->id[0] == m2->id[0]){ return m1->id[1] < m2->id[1]; } return m1->id[0] < m2->id[0]; } }; std::set<ABC_PTR, CompareABC> g_ABCSet; // 查找函数示例 void findABCById(const byte targetId[2]) { // 构造临时ABC对象,只需要设置目标id,name不影响查找(因为比较器只看id) auto tempABC = std::make_shared<ABC>(); memcpy(tempABC->id, targetId, sizeof(tempABC->id)); auto it = g_ABCSet.find(tempABC); if (it != g_ABCSet.end()) { // 找到匹配元素 wprintf(L"Found element: name = %s, id = 0x%02X%02X\n", (*it)->name.GetString(), (*it)->id[0], (*it)->id[1]); } else { wprintf(L"Element with id 0x%02X%02X not found\n", targetId[0], targetId[1]); } }
调用的时候只需要传入目标id数组即可,比如:
byte target[2] = {0x01, 0x02}; findABCById(target);
方案二:用std::find_if线性遍历查找(更灵活)
如果你不想构造临时对象,或者需要更复杂的匹配逻辑,可以用std::find_if结合lambda表达式遍历整个set。这种方法是线性时间复杂度O(n),适合元素数量不多的场景。
代码示例:
#include <algorithm> // 用于std::find_if void findABCByIdLinear(const byte targetId[2]) { auto it = std::find_if(g_ABCSet.begin(), g_ABCSet.end(), [&targetId](const ABC_PTR& ptr) { // 直接比较两个id字节是否完全匹配 return ptr->id[0] == targetId[0] && ptr->id[1] == targetId[1]; }); if (it != g_ABCSet.end()) { wprintf(L"Found element: name = %s, id = 0x%02X%02X\n", (*it)->name.GetString(), (*it)->id[0], (*it)->id[1]); } else { wprintf(L"Element with id 0x%02X%02X not found\n", targetId[0], targetId[1]); } }
关键注意事项
- 确保比较器的排序逻辑和查找时的匹配逻辑一致:你的比较器是按
id[0]优先、id[1]次之的顺序排序,查找时必须保证两个字节都相等才视为匹配,这样才不会出现逻辑错误。 - 构造临时对象时,不需要初始化
name成员,因为CompareABC只比较id,set的find方法只会根据比较器的规则来判断是否匹配。
内容的提问来源于stack exchange,提问作者pushE
相关产品推荐
相关产品推荐

