C++组插件如何与自定义比较器配合使用

How C++ set insert work with custom comparator

本文关键字:比较器 自定义 插件 C++      更新时间:2023-10-16

我正在拧一组指针

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 个条目。

从 http://www.cplusplus.com/reference/set/set/开始(在 Compare 模板参数上(:

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

从标准§23.2.4:

  1. 每个关联容器在键和排序上参数化关系 比较,诱导严格的弱排序 (25.4( 上元素。此外,映射和多重映射关联任意使用键映射类型 T。比较类型的对象称为容器的比较对象。

  2. 短语"钥匙的等效性"表示比较强加的等价关系,而不是运算符== 在键上。也就是说,两个键 k1 和 k2 被认为是等价的 if 对于比较对象 comp, comp(k1, k2( == false &&comp(k2, k1( == false.对于同一中的任意两个键 k1 和 k2容器,调用 comp(k1, k2( 应始终返回相同的值。

和§23.4.6.1(强调是我的(:

  1. 集合满足容器、可逆容器 (23.2(、关联容器的所有要求 容器 (23.2.4( 和分配器感知容器(表 99(。

从评论中复制以继续讨论

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

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

在标准库使用 Compare 概念的任何地方,唯一性都是通过使用等价关系来确定的。在不精确的术语中,如果两个对象 a 和 b 的比较都不比另一个少,则两个对象 a 和 b 被认为是等价的(不唯一的(:!comp(a, b( && !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;
}