Search code examples
c++sortingstloperator-overloadingstl-algorithm

Overloading comparison operators to work with STL sort in C++


I am writing a program that will read in a list of names with social security numbers (not real ones of course) and sort the list based on either last name or ssn, depending on a command line argument. I have overloaded the < operator and also overloaded input and output operators for simplicity. Everything compiles fine until I add the sort function and the output at the end of main. I'm stumped. Any ideas? Any other tips are also greatly appreciated.

#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <fstream>
using namespace std;

enum sortVar { NAME, SOCSEC };

class record {
    public:
        friend bool operator<(record& rhs, record& name);
        friend ostream& operator<<(ostream& out, record& toWrite);
        friend istream& operator>>(istream& in, record& toRead);
        bool t_sort;    
    private:
        string firstName, lastName, ssn;

};

bool operator<(record& rhs, record& next)
{
    if (rhs.t_sort = false) {
        if (rhs.lastName == next.lastName)
            return rhs.firstName < next.firstName;
        else
            return rhs.lastName < next.lastName;
    }
    else if (rhs.t_sort = true)
        return rhs.ssn < next.ssn;
}

ostream& operator<<(ostream& out, record& toWrite)
{
    out << toWrite.lastName 
         << " " 
         << toWrite.firstName 
         << "    " 
         << toWrite.ssn;
}

istream& operator>>(istream& in, record& toRead)
{
    in >> toRead.lastName >> toRead.firstName >> toRead.ssn;
}

int main(int argc, char* argv[])
{
    if (argc !=3) {
        cerr << "Incorrect number of arguments.\n";
        exit(1);
    }
    if (argv[1] != "name" || argv[1] != "socsec") {
        cerr << "Argument 1 must be either 'name' or 'socsec'.\n";
        exit(1);
    }

    sortVar sortMode;
    if (argv[1] == "name")
        sortMode = NAME;
    else if (argv[1] == "socsec")
        sortMode = SOCSEC;

    ifstream fin(argv[2]);

    vector<record> nameList;
    while(!fin.eof()) {
        record r;
        if (sortMode == NAME)
            r.t_sort = false;
        else if (sortMode == SOCSEC)
            r.t_sort = true;
        fin >> r;
        nameList.push_back(r);
    }

    //sort(nameList.begin(), nameList.end());
    //cout << nameList;

}

Solution

  • This is kind of strange, and something your compiler should warn about

    if (rhs.t_sort = false)
    

    You are not testing the value of t_sort but always setting it to false.

    Testing a bool against true or false is bit unnecessary anyway, as this is what the if-statement is doing already.

    Try this code instead

    bool operator<(const record& rhs, const record& next)
    {
        if (rhs.t_sort) {
            return rhs.ssn < next.ssn;
        }
        else
        {
            if (rhs.lastName == next.lastName)
                return rhs.firstName < next.firstName;
            else
                return rhs.lastName < next.lastName;
        }
    }