版权声明: 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时有可能会出错.