C ++ set insert如何与自定义比较器一起使用

时间:2015-12-23 07:50:21

标签: c++ c++11

我正在拧一组指针

class CLwObj {
private:
string name ;
int type ;

public:
CLwObj() {}
CLwObj(string val, int typ) { name =val ; type = typ; }

string getName() { return name; }
int getType() { return type; }
};

class CLwObjCompare
{
    public:
    bool operator () (CLwObj* obj1, CLwObj* obj2) const
    {
        bool val =  ((obj1->getName().compare(obj2->getName()) < 0) ) ;
        return val;
    }
};

int main ()
{
    set<CLwObj*, CLwObjCompare> myset ;

    CLwObj *obj1 = new CLwObj("hello", 1);
    CLwObj *obj2 = new CLwObj("kello", 1);
    CLwObj *obj3 = new CLwObj("hello", 1);

    myset.insert(obj1);
    myset.insert(obj2);
    myset.insert(obj3);
    return 0;
}

请解释插入如何使用自定义比较器,我只得到两个条目,因为两个具有相同的名称。

我认为比较功能只决定了订单 所有对象都有不同的地址,因此应该有3个条目。

2 个答案:

答案 0 :(得分:2)

来自http://www.cplusplus.com/reference/set/set/(在Compare模板参数上):

  

set对象使用这个表达式来确定元素在容器中遵循的顺序以及两个元素键是否相等(通过反思地比较它们:如果!comp(a,b)它们是等价的)&amp;&amp;!comp(b,a))。集合容器中没有两个元素可以等效。   这可以是函数指针或函数对象(请参阅示例的构造函数)。

来自standard,§23.2.4:

  
      
  1. 每个关联容器都在Key和一个排序上进行参数化   关系比较会导致严格的弱排序(25.4)   Key的元素。另外,map和multimap关联任意   使用Key映射类型T. Compare类型的对象称为   容器的比较对象。

  2.   
  3. 短语“等价键”   是指比较所强加的等价关系,而不是   operator == on key。也就是说,认为两个键k1和k2是   如果对于比较对象comp,comp(k1,k2)== false&amp;&amp;   comp(k2,k1)== false。对于任何两个键k1和k2在同一个   容器,调用comp(k1,k2)应始终返回相同的值。

  4.   

并且§23.4.6.1(重点是我的):

  
      
  1. 一套满足容器,可逆容器(23.2),关联的所有要求   容器(23.2.4),以及分配器感知容器(表99)。
  2.   

答案 1 :(得分:0)

从评论中复制以继续讨论

您通过了比较器CLwObjCompareset使用该比较器来确定2个对象是否相同。

请参阅http://en.cppreference.com/w/cpp/container/set

  

标准库的所有地方都使用Compare概念,唯一性由等价关系决定。不精确的说,如果两个对象的比较小于另一个,则认为两个对象a和b是等价的(不是唯一的):!comp(a,b)&amp;&amp; !comp(b,a)

继续讨论

以下是我的建议:

class CLwObj {
private:
    string name ;
    int type ;

public:
    CLwObj() {}
    CLwObj(string val, int typ) { name =val ; type = typ; }

    string getName() const { return name; }
    int getType() const { return type; }
};

class CLwObjCompare
{
public:
    bool operator () (const CLwObj& obj1, const CLwObj& obj2) const
    {
        return lhs.getName() < rhs.getName() && lhs.getType() < rhs.getType();
    }
};

int main ()
{
    set<CLwObj, CLwObjCompare> myset ;

    myset.emplace("hello", 1);
    myset.emplace("kello", 1);
    myset.emplace("hello", 2);
    return 0;
}