Jake Smith
Jake Smith

Reputation: 199

Using the sort algorithm C++

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

Answers (3)

Adrian McCarthy
Adrian McCarthy

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

Vlad from Moscow
Vlad from Moscow

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

David G
David G

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

Related Questions