If I have a class
class Point
{
public:
Point() {}
Point(int _col, int _row) : row(_row), col(_col) {}
int row, col;
};
how can I use std
Unless your types are PODs fundamental types, you will need to provide an equality function, member or not.
There are two fundamental versions of std::find
, one that assumes an equality operator and the other uses an equality function you supply.
I recommend that you add operator==
and operator<
to any class that will be compared for equality or ordered.
Here's an updated version of your class:
class Point
{
int x; // These are private by default.
int y;
public:
Point(int new_x, int new_y) : x(new_x), y(new_y)
{ ; }
bool operator==(const Point& p) const
{
return (x == p.x) && (y == p.y);
}
};
The member method operator==
allows comparison without exposing the values to friends or the public.
If you want to use a free standing comparison function, you will need to either make the values public or make the function a friend:
class Point
{
int x; // These are private by default.
int y;
public:
Point(int new_x, int new_y) : x(new_x), y(new_y)
{ ; }
friend bool operator==(const Point& a, const Point& b);
};
bool operator==(const Point& a, const Point& b)
{
return (a.x == b.x) && (a.y == b.y);
}
If you want to use the free standing function with std::find
, the example would be:
std::vector<Point> point_container;
//...
Point p;
std::vector<Point>::const_iterator iter;
iter = std::find(point_container.begin(), point_container.end(),
p,
Equal_Points);
Where Equal_Points
is a free standing function that can compare the members of two Points.
The C++ standard (draft N3242) says (in section 25.2.5 [alg.find]) that std::find
:
Returns: The first iterator
i
in the range[first,last)
for which the following corresponding conditions hold:*i == value
[...]. Returnslast
if no such iterator is found.
Your question of whether it will search based on the value or the address of the object depends on how operator==
is implemented. The simple answer is: std::find
will return an iterator to the object for which operator==
returned true.
Usually, this will just be a value-based comparison (because operator==
is usually implemented to compare the values of two objects), and so you should generally expect std::find
to search the range for the value you've provided (not the address of the object you provided).
It's possible for operator==
to be implemented such that it compares based on address, like so:
bool operator==(const Point& left, const Point& right) {
return &left == &right;
}
Using this operator==
will compare addresses, and so std::find
will search for an object that has the same address as the one you've provided. It's generally a bad idea to implement operator==
like this, though. Most people would implement operator==
like so:
bool operator==(const Point& left, const Point& right) {
return left.row == right.row && left.col == right.col;
}
which, when used with std::find
, will compare Points based on their values.