0

My code is as below. I have as struct ABC and i have set g_ABCSet to compare the id.

struct ABC
{
CString name;
byte id[2];
}

typedef shared_ptr<ABC> ABC_PTR;

std::set<ABC_PTR, CompareABC> g_ABCSet;

class ComparePager{
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];
    }
}

I try to search in set as below comparing the id

static ABC_PTR ABCptr(new ABC);
//Assume ABCptr have some valid ID 
auto it = g_ABCSet.find(ABCptr);
if (it == g_ABCSet.end())
 {
//not found
}
else
{
 //found one
}

My query here is can i use the same set to compare the "Cstring name" in the ABC struct.

If YES HOW ??

IF NO , DO i need to make same new set ,overlaod operator to comparing Cstring and insert all same pointers to new set also ??

4

1 回答 1

1

不,您不能使用单个 std::set。

原因:因为该集合要求键处于“严格排序”状态。该集合很可能使用树结构来存储它的项目,并且树由给定的比较器排序。

这也意味着如果您插入多个具有不同名称和相同 ID 的项目,则根本只存储一个项目(因为比较器说它们都是相同的)

您可以使用 std::find_if 搜索Cstring name

CString searchName = "...";
auto it = std::find_if(
  g_ABCSet.begin(), 
  g_ABCSet.end(), 
  [&](const ABC_PTR& ptr) {
     return ptr->name == searchName;
  });

如果您在 g_ABCSet 中有大量项目,您应该按照您所写的那样做:为“名称”创建第二个带有 Comparator 的集合。

提示:如果您使用Comparatorstd::array<byte, 2> id而不是byte id[2]您的 Comparator ,则可以像这样简单

class ComparePager{
public:
    bool operator()(const ABC_PTR& m1, const ABC_PTR& m2) const {
        return m1->id < m2->id;
    }
}

也许您最好使用 astd::map<std::array<byte, 2>, ABC_PTR>和 anotherstd::map<CString, ABC_PTR>来完成这项工作。这需要更多内存(主要是因为 CString 从 g_ABCSet 复制到地图中)但完全摆脱了自定义比较器,并且您不会意外使用错误的集合(使用错误的比较器)

于 2018-04-18T06:49:21.723 回答