Reputation: 199
I'm reading in a list of names and I want to order the last names by which comes first alphabetically. the file will contain contents like this
Smith John 467-604-4535
Kidd Jason 433-243-5252
etc
class record
{
bool operator <(const record &rhs) const
{
return (lastname < rhs.lastname)
}
private:
string fn, ln, pn;
};
int main(int argc, char *argv[])
{
record data;
ifstream fs;
fs.open(arg2.c_str());
vector<record> vec;
while (fs >> data)
{
vec.push_back(data);
}
fs.close();
sort (vec.begin(), vec.end(), data);
for (int i=0; i < vec.size(); i++)
cout << vec[i];
}
The line of code that is giving me the error is the sort (vec.begin(), vec.end(), data) It's giving me a ton of errors. Everything else from my knowledge is working though. It's just sort. Any ideas what is wrong with the sort? How can I sort the vector?
Upvotes: 1
Views: 203
Reputation: 47954
You call sort with a pair of iterators and (optionally) a callable object that knows how to compare two items of the type you are sorting. If you don't provide the optional comparator, sort will attempt to use operator<
on the items.
Note that the comparator must implement strict weak ordering. That means that your comparator must be completely consistent. Your operator<
example is not completely consistent. If you have two employees with the same last name (e.g., "Smith, Jane" and "Smith, John") you cannot simply compare last names because you won't get consistent results. If the last names don't tell you which one comes first, then you must compare first names. And so on. Here's an example:
struct comparator {
bool operator()(const record &lhs, const record &rhs) {
if (lhs.lastname < rhs.lastname) return true;
if (lhs.lastname == rhs.lastname) {
if (lhs.firstname < rhs.firstname) return true;
if (lhs.firthname == rhs.firstname) {
// ... compare other fields ..
}
}
return false;
}
};
Without strict weak ordering, you may get lucky (some data sets might appear to work), you might get misordered data, you might even crash. It depends on the details of the sort implementation and the particular data set you give it.
With a proper functor for comparisons, you can call sort like this:
sort(vec.begin(), vec.end(), comparator());
Upvotes: 0
Reputation: 310910
Use instead
sort (vec.begin(), vec.end());
Also it is not clear what this statement means
fs.open(arg2.c_str());
Where is arg2 is defined?
Upvotes: 0
Reputation: 96790
std::sort()
invokes operator()
on its third given argument. It requires a callable object (a functor) to be used as the predicate for sorting. Your predicate doesn't supply one and thus a compilation error.
But the details of std::sort
specify that it will use operator<
on the each of the elements if you do not supply your own:
std::sort(vec.begin(), vec.end());
To elaborate, there are two overloads of std::sort
, one that uses operator<
, and the other that uses the custom sorting functor.
On a second look at your code, it appears you've only overloaded operator<
for a righthand side of std::string
. You have to overload operator<
for two record objects at a time.
Inside the class you would tag it as a friend
:
friend bool operator<(const record& lhs, const record& rhs)
{
return lhs.lastname < rhs.lastname;
}
Upvotes: 2