如何在std :: set中为唯一元素插入提供比较函数?

时间:2015-11-05 14:32:52

标签: c++ stl set operator-overloading

我有以下用户定义的类

class simple
{
public:
  simple(string str1, string str2)
   : s1(str1)
   , s2(str2)
  {
  }
  const string& getS1() const {return s1;}
  const string& getS2()const {return s2;} 
  bool operator<(const simple& s) {
    return strcmp(this->getS1().c_str(), s.getS1().c_str()) < 0 && strcmp(this->getS2().c_str(), s.getS2().c_str()) < 0;
  }
private:
  const string s1;
  const string s2;
}

我将此类存储在std :: set中,如下所示:

std::set<simple*> mySimplePtrSet;
simple* s1 = new simple("stack", "overflow");
simple* s2 = new simple("go", "ogle");
simple* s3 = new simple("stack", "overflow");
simple* s4 = new simple("go", "good");
simple* s5 = new simple("my", "overflow");

在上面的示例中,set应该只包含s1,s2,s4和s5。

如何考虑类的数据成员(即s1和s2)来存储集合中的唯一类对象?

我尝试使用以下隔离功能,但它无效。

struct myCom {
   bool operator()(const simple* a,const simple* b){
      return *a < *b;
   }
};

注意:排序在我的情况下并不重要,如果未插入的元素对我来说很好。

1 个答案:

答案 0 :(得分:0)

您存储指针,因此比较器只是比较内存地址,而不是您的自定义operator<

停止使用new并将实际对象存储在地图中:

std::set<simple> mySimpleSet;
mySimpleSet.emplace("stack", "overflow");
mySimpleSet.emplace("go", "ogle");
mySimpleSet.emplace("stack", "overflow");
mySimpleSet.emplace("go", "good");
mySimpleSet.emplace("my", "overflow");

或者如果确实需要存储指针,那么你必须提供一个自定义比较器,它不会比较内存地址,而是比较这些内存地址的对象。

你的operator<也有缺陷。您正在使用std::string,因此请使用std::string::compare代替strcmp,并且您未使用参数s。这样的事情会更好:

bool operator<(const simple& s) {
  return getS1() < s.getS1() && getS2() < s.getS2();
}