C++ : struct vs function for ordering elements

It's easier to define both as structures, because you can always create an object from a type and it will behave as expected, but getting a type from a function and having it act as a caller for the function is much more difficult.

You were in fact almost there with struct cmpFrom. However, you've correctly noted that std::sort expects a comparator object (such as a function), not a type. Of course, doing &cmpFrom where cmpFrom is a type is not valid C++. Instead, you need to create an object of that type; thanks to the operator() defined, the object will be callable and do what you want. So just call std::sort like this:

std::sort(trips, trips + nbRoads, cmpFrom{});

You almost have it. In std::sort you need an object that you can call operator() on. Using

bool cmpFrom (const road & a, const road & b) {
    return (a.from < b.from) ;
}
std::sort(trips, trips + nbRoads, &cmpFrom);

works because a function pointer can be used like a function. When you change cmpFrom to

struct cmpFrom {
    bool operator () (const road & a, const road & b){
        return (a.from < b.from) ;
    }
};

you can't use std::sort(trips, trips + nbRoads, &cmpFrom); anymore because you can't apply & to a type name. Instead what you need to do is get an object of cmpFrom and you do that like

std::sort(trips, trips + nbRoads, cmpFrom{});

now both the priority_queue and sort could use cmpFrom.


The std::sort function and std::priority_queue class template want two different things: sort wants a callable object, while priority_queue template wants a type, which allows creating objects.

Because of that, sort is more omnivorous than priority_queue - you can use it with either functions or functors. The only thing you need is to provide it with a real object (while currently in your code you are trying to take an address of a type, which makes no sense).

To fix it in your example just change the code to

std::sort(trips, trips + nbRoads, cmpFrom{});