集合类的错误使用

本文详细解析了C++ STL中set和map容器的工作原理,重点介绍了如何自定义比较函数,以及在插入和查找操作中比较函数的作用。通过一个具体的Person类实例,展示了在set中指定自定义比较函数可能导致的查找行为差异。
最近在回答一些群组里的问题,记录一下

std::set / map 是有序的,通过第2个函数[对象]来进行比较,然后插入;因此在insert/find时都会调用比较函数.

一个错误例子:

struct Comp{
    template <typename T>
    bool operator()(const T & a, const T& b){
        return a.age() > b.age();
    }
};
class Person{
    int m_age;
    std::string m_name;
public:
    Person(int a, std::string name) : m_age(a),m_name(std::move(name)){}
    int age()const{return m_age;}
    const std::string& name() const {return m_name;}
    void print()const {cout << "name:" << m_name << ",age:" << m_age;}

    //如果没有比较函数则调用此函数
  /*  bool operator<(const Person & p) const{
        cout << "operator<" <<endl;
        return m_age < p.age();
    }
    */

    //用于std::find
    bool operator== (const Person& p)const{
        cout << "operator==" <<endl;
        return m_age == p.age() && m_name == p.name();
    }
    friend ostream& operator<<(ostream& os ,const Person& p){
        return os <<"|" <<p.age() <<":" << p.name() <<"|" ;
    }
};

    std::set<Person,Comp> s; //指定了比较函数对象,不论插入还是查找都使用此函数
    s.insert(Person(1,"a"));
    s.insert(Person(2,"b"));
    s.insert(Person(3,"c"));
    print(s.begin(),s.end());

     //还是找到了,因为使用了函数对象,其中只比较了年龄,对于set::find来说就使用这个比较函数
    cout << *(s.find(Person(1,"b")))  << endl;

     //std::find则将使用operator == 来做比较
    auto iter = std::find(s.begin(),s.end(),Person(1,"a"));
    cout <<( iter == s.end()) << endl;

对于set来说不论是插入还是查找都将使用比较函数[默认less<>] , 因此在set::find时有可能会出错.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值