集合类的错误使用

版权声明: https://blog.csdn.net/dashoumeixi/article/details/89679981
最近在回答一些群组里的问题,记录一下

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时有可能会出错.

猜你喜欢

转载自blog.csdn.net/dashoumeixi/article/details/89679981