0

Yes, I know this is a repeat question and I already know that the anwser im looking for is here:

Sorting a vector of objects by a property of the object

However I have problems converting this to my own code. I'm looking at this code snippet from the above question:

struct SortByX
{
    bool operator() const(MyClass const& L, MyClass const& R) {
        return L.x < R.x;
    }
};

std::sort(vec.begin(), vec.end(), SortByX();

What I do not understand is what is being represented by MyClass const & L, and MyClass const & R. And I am not grasping how I can apply this to my code.

To give a bit more detail I am putting 3 sort methods into a wrapper class of a vector of objects that have parameters of (string, double, double, double, bool). And the over all goal is to sort the vector by the string, the bool and any one out of the 3 doubles.

This is the lastest version I have:

void StationVector::sortByGrade(int kindOfGas) {
struct SortByGrade {
    int kindOfGas;

    SortByGrade(int kindOfGas) :
            kindOfGas(kindOfGas) {
    }

    bool operator()(GasStation const &L, GasStation const & R) const {
        return L.getPrice(kindOfGas) < R.getPrice(kindOfGas);
    }
};

std::sort(localStations.begin(), localStations.end(),
        SortByGrade(kindOfGas));
}

the line SortByGrade(kindOfGas)) gives me the following error:

no matching function for call to `sort(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, model::StationVector::sortByGrade(int)::SortByGrade)'

5
  • MyClass represents the type stored by your vector. Commented Feb 10, 2013 at 22:45
  • MyClass should be replaced by whatever kind of objects are stored in your vector. Commented Feb 10, 2013 at 22:46
  • What does the compiler say is the error? Don't leave us guessing! Commented Feb 11, 2013 at 1:46
  • The error was that a ; was out of place. which i don't think is the actual issue Commented Feb 11, 2013 at 2:07
  • I've updated my answer to demonstrate how to put together an SSCCE. You're going to need to provide enough code to reproduce this error (but, critically, no more) for us to help you further. Commented Feb 11, 2013 at 3:24

2 Answers 2

2

SortByX is a binary predicate functor. Binary predicate means it takes two arguments and returns a boolean. Functor means it's instances are callable. For example:

MyClass a = ....;
MyClass b = ....;
SortByX comp;
bool flag = comp(a,b); // call this SortByX instance with two MyClass instances

Now, std::sort will internally use a copy of the instance of SortByX that you pass it in order to perform the comparisons between the elements of a std::vector<MyClass> needed to sort that vector.

std::vector<MyClass> v;
// fill the vector with MyClass objects
std::sort(v.begin(), v.end(), SortByX()); // sort the vector using a SortByX instance for comparisons

Note: for this to work, the binary predicate must implement strict weak ordering.

Sign up to request clarification or add additional context in comments.

2 Comments

So If im reading this correctly This explains how SortByX works but now how to implement it.
@Nood the SortByX implementation that you posted shows you exactly how this thing can be implemented. Looking at your edit, it looks like you got it.
1

What I do not understand is what is being represented by MyClass const & L, and MyClass const & R.

L and R, in this case are two items (instances of your class MyClass) from the container that are being compared, with L on the left of the less-than operator and R on the right. They are passed in by const-reference.

And I am not grasping how I can apply this to my code.

In your own bool operator() const(MyClass const& L, MyClass const& R), you need to compare the three data members you mention in your question, vitally remembering to apply strict weak ordering. Return true if L is "less than" R and false otherwise.


Following updates to the question...

It looks like you wish to pass a variable into your functor. You do this by creating a constructor, like this SSCCE (which compiles here):

#include <algorithm>
#include <vector>

namespace model {

struct GasStation
{
    double getprice(int kindOfGas) const
    {
        return kindOfGas;
    }
};

struct StationVector
{
    std::vector<GasStation> localStations;

    struct SortByGrade
    {
        int kindOfGas_;
        SortByGrade(int kindOfGas)
            :kindOfGas_(kindOfGas)
        {
        }

        bool operator() (GasStation const &L, GasStation const & R) const
        { 
            // You'll need other comparisons here, but this is a good start...
            return L.getprice(kindOfGas_) < R.getprice(kindOfGas_); 
        }
    };

    void sortByGrade(int kindOfGas) 
    {
        std::sort(localStations.begin(), localStations.end(), SortByGrade(kindOfGas));
    }
};

}

int main()
{
    model::StationVector sv;
    sv.sortByGrade(0);
}

Note: The const qualifier comes after the argument list and not after the method name.

Also, please don't put the entire method on one line, it makes it very difficult to read.

15 Comments

Im still not understanding how to implement the code properly. Can you show me an example
Trying the above example is getting an error stating "passing const model::GasStation' as this' argument of `double model::GasStation::getPrice(int)' discards qualifiers" I'm not sure what thats trying to tell me.
double model::GasStation::getPrice(int) should be declared const (unless it somehow modifies the state of the object, in which case it's not likely to be a good candidate to use in a comparator).
Meaning? I changed double GasStation::getPrice(int){ to double const GasStation::getPrice(int){ That didn't change anything. Did i misunderstand what you were trying to say?
The best advice I can give at this time is stop programming until you have fixed your environment and you can run and test your code. Here is an example of sorting including the bool values: ideone.com/lmyqOi
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.