Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to name comparison predicate function to sort vector

Tags:

c++

I'm a beginner at C++ and have a question regarding sorting a vector of a class object. I've done a lot of research online but can't seem to figure out the answer. My problem is that I want to have multiple predicate comparison functions that I can name, as I need to have the user be able to choose from a menu which private member variable/component of the vector to sort on. I'm able to get a predicate comparison function with an overloaded operator to work ok, but when I try and name the function, I can't seem to get it to compile without a bunch of errors (which I'll post farther down underneath the appropriate code).

When the code's run, a vector of a BookData object is created by a function that reads a text file. Function prototype in main:

vector<BookData> createVector();

Function call in main:

vector<BookData> books = createVector();

createVector function definition:

vector<BookData> createVector()
{
    const int LENGTH = 81;
    char input[LENGTH];
    vector<BookData> fBooks;
    string vBookTitle, vIsbn, vAuthor, vPublisher, vDateAdded;
    int vQtyOnHand;
    double vWholesale, vRetail;
    BookData *books1;
    books1 = new BookData;
    fstream dataFile("Serendipity.data");
    if (dataFile.is_open())
    {
        while (!dataFile.eof())
        {
            dataFile.getline(input, LENGTH, '\t');
            vBookTitle = input;
            books1->setTitle(vBookTitle);
            dataFile.getline(input, LENGTH, '\t');
            vAuthor = input;
            books1->setAuthor(vAuthor);
            dataFile.getline(input, LENGTH, '\t');
            vPublisher = input;
            books1->setPub(vPublisher);
            dataFile.getline(input, LENGTH, '\t');
            vIsbn = input;
            books1->setIsbn(vIsbn);
            dataFile >> vQtyOnHand;
            books1->setQty(vQtyOnHand);
            dataFile >> vWholesale;
            books1->setWholesale(vWholesale);
            dataFile >> vRetail;
            books1->setRetail(vRetail);
            dataFile.ignore();
            dataFile.getline(input, LENGTH);
            vDateAdded = input;
            books1->setDateAdded(vDateAdded);
            fBooks.push_back(*books1);
        }
    }
    return fBooks;
}

This is my class definition file (bookdata.h) with the working comparison function:

class BookData
{ 
private:
        string bookTitle, isbn, author,
            publisher, dateAdded;
        int qtyOnHand;
        double wholesale, retail;
        bool empty;     

public:
    BookData();
    bool operator< (BookData rhs);
    void printVector();
    void setTitle(string);
    void setIsbn(string);
    void setAuthor(string);
    void setPub(string);
    void setDateAdded(string);
    void setQty(int);
    void setWholesale(double);
    void setRetail(double);
    int isEmpty();
    void insertBook();
    void removeBook();
    string getTitle();
    string getIsbn();
    string getAuthor();
    string getPublisher();
    string getDateAdded();
    int getQtyOnHand();
    double getWholesale();
    double getRetail();
};

And this is the working function in the class implementation file (bookdata.cpp):

bool BookData::operator< (BookData rhs)
{
    return qtyOnHand < rhs.qtyOnHand;
}

And it's called like so from int main():

sort (books.begin(), books.end());

However, if I try and name the function:

bool compare (BookData rhs);

from within the class definition file and change it to this in the class implementation file:

bool BookData::compare (BookData rhs)
{
    return qtyOnHand < rhs.qtyOnHand;
}

and change the vector sort function so within main:

sort (books.begin(), books.end(), &BookData::compare);

I get an error message from the compiler:

error C2064: term does not evaluate to a function taking 2 arguments

Any suggestions as to how I can properly name/call the sort function?

like image 510
Evan R Avatar asked Apr 07 '26 06:04

Evan R


1 Answers

The Compare shouldn't be a member of the class (or be a static member or friend if it accesses restricted fields), and it should accept both the values to compare (whereas operator < uses this as the left value).

something like this:

bool compare (BookData lhs, BookData rhs)
{
    return lhs.qtyOnHand < rhs.qtyOnHand;
}

Using operator< is IMHO a better approach.

like image 138
littleadv Avatar answered Apr 08 '26 19:04

littleadv