如何解决std :: set比较器
我正在使用自定义比较器测试std::set
。但是我看到同一对象被插入两次。
以下是对象类:
class Info
{
public:
Info(string n,string oN,int dom):
name(n),objName(oN),domain(dom)
{}
void setName(std::string n) { name = n;}
void setObjName(std::string n) { objName = n;}
void setDomain(int dom) { domain = dom; }
std::string getName() const { return name;}
std::string getObjName() const { return objName;}
int getDomain() const { return domain;}
private:
std::string name;
std::string objName;
int domain;
};
以下是我的自定义比较器:
struct InfoCmp {
bool operator() (const Info &lhs,const Info &rhs) const {
if((lhs.getName() < rhs.getName()) || (lhs.getObjName() < rhs.getObjName()) || (lhs.getDomain() < rhs.getDomain()) ){
return true;
}
return false;
}
};
以下是用法:
Info rst1("rst1","rstObj1",1);
Info rst2("rst2","rstObj2",2);
Info rst3("rst1","rstObj3",3);
std::set<Info,InfoCmp> resetSet;
resetSet.insert(rst1);
resetSet.insert(rst2);
resetSet.insert(rst3);
resetSet.insert(rst1);
resetSet.insert(rst2);
resetSet.insert(rst3);
我看到rst2
插入了两次,但是不应该与我的比较器相同。
解决方法
从评论中得知您的原件并未按照set
的要求对对象进行严格的排序后,我发现您已经提出了自己的解决方案。这是另一种版本,仅需要operator<
而不需要operator==
,使其与标准库的类和算法一致。如果您是例如,它还简化了事情。做不区分大小写的比较。
struct InfoCmp {
bool operator() (const Info &lhs,const Info &rhs) const {
if(lhs.getName() < rhs.getName())
return true;
if(rhs.getName() < lhs.getName())
return false;
if(lhs.getObjName() < rhs.getObjName())
return true;
if(rhs.getObjName() < lhs.getObjName())
return false;
return lhs.getDomain() < rhs.getDomain();
}
};
,
struct InfoCmp2 {
bool operator() (const Info &lhs,const Info &rhs) const {
return std::make_tuple(lhs.getName(),lhs.getObjName(),lhs.getDomain()) < std::make_tuple(rhs.getName(),rhs.getObjName(),rhs.getDomain());
}
};
该运算符也可以用make_tuple
编写,并且工作正常。
如Cory Kramer所建议,在比较器中添加严格的排序可以解决此问题。
struct InfoCmp {
bool operator() (const Info &lhs,const Info &rhs) const {
if((lhs.getName() < rhs.getName())
|| ( (lhs.getName() == rhs.getName()) && (lhs.getObjName() < rhs.getObjName()) )
|| ( (lhs.getName() == rhs.getName()) && (lhs.getObjName() == rhs.getObjName()) && (lhs.getDomain() < rhs.getDomain()) )){
return true;
}
return false;
}
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。