Solved Functor. Implementing comparator with additional parameter
-
Hi.
Im trying to implement a comparator to sort my QList<Custom>. Problem ist, the comparator for qSort obv have to be a static function, just taking two arguments. But i need a third argument, so i can do my comparison, or i need somehow to access member variables of my class. Is there a way to do this?
I came across something called functor, that somehow make a subclass of myclass and then use member variables and implementing "operator()" , but i dont get how to do it and if its even possible with the signal and slot stuff. -
Hi,
Can you show a sample of how you would like to do your comparison ?
-
Well, i have a QList<Village> containing villages with a name and two coordinates. I have a program that display i number of villages in a TableView. I want to sort the villages with respect to their distance to a specific targetvillage. Which means the sorting changes every time the targetvillage is changed. This means i need an additional argument for the comparison, namely a pointer, reference or whatever for the current targetvillage.
class Village { public: ... private: QString villageName; int x; int y; };
so far i had something like
void TableDataModel::sort(int column, Qt::SortOrder order) { qSort(villageList->begin(), villageList->end(), compareTwoVillageLessThan); } bool TableDataModel::compareTwoVillageLessThan(const Village &A, const Village &B ) { Village tempTargetVillage = *targetVillage; double distanceA = calculateDistance::getCalculateDistance(A, tempTargetVillage, c); double distanceB = calculateDistance::getCalculateDistance(B, tempTargetVillage, c); return distanceA < distanceB; }
but then i realized the comparator have to be static and i cant access class member.
-
Use a functor:
class CompareTwoVillages { private: const Village refVillage; public: CompareTwoVillages(const Village &village) : refVillage(village) { } bool operator () (const Village& leftVillage, const Village& rightVillage) { bool result = false; // implement algorithm return result; } };
And then call:
qSort(villageList.begin(), villageList.end(), CompareTwoVillages(targetVillage));
By the way, why do you allocate your QList on the heap ? That's usually not needed.
-
@Maser
I have two tiny remarks to the otherwise excellent guidance provided by @SGaist:- You could use a lambda function (which internally is a functor) instead of writing a whole class. It's just a more compact notation for what Samuel suggested.
- You should use
std::sort
instead ofqSort
, asqSort
is marked obsolete in Qt 5.
Kind regards.
-
Thank you very much, guys))
Your example helped me a lot, SGaist. Although i had to do a bit of reading on functors and function pointers to fully understand the concept.
I let it sink in a bit, and then im gonna read some more on lambdafunctions as kshegunov suggested.
Thubms up!