C++ std list sort with custom comparator that depends on an member variable for the object instance
Solution 1
@Kerrek's answer involving lambdas is better. But, if you must avoid C++11 features, then replace your sort function with a functor. Allow that functor to store a reference to whatever data is required, as so:
#include <vector>
#include <list>
#include <string>
class myClass {
private:
std::vector<std::string> words;
std::vector<std::list<int> > vints;
// Instead of sortFunc, use sortFunctor. A functor can be used in place
// of a function in many places, and it can carry state (like a reference
// to the data it needs).
struct sortFunctor {
const std::vector<std::string>& words;
sortFunctor(const std::vector<std::string>& words) : words(words) { }
bool operator()(int i, int j) { return words[i] < words[j]; }
};
public:
void myFunction() {
vints[0].sort(sortFunctor(words));
}
myClass() {
words.push_back("apple");
words.push_back("berry");
std::list<int> l;
l.push_back(0);
l.push_back(1);
vints.push_back(l);
}
};
int main () {
myClass object;
object.myFunction();
}
Solution 2
With lambdas:
vints[i].sort([&words](int i, int j) { return words[i] < words[j]; });
With std::bind
:
#include <functional>
//...
{
using namespace std::placeholders;
vints[i].sort(std::bind(&myClass::sortFunc, this, _1, _2));
}
encore2097
Updated on June 04, 2022Comments
-
encore2097 almost 2 years
Class:
Class: private: ... vector<string> words; vector< list<int> > vints; public: myFunction(...)
I am calling a sort on non-empty list in another member function:
void myClass::myFunction (...) { ... if (!vints[i].empty()) vints[i].sort(sortFunc); ... }
My sorting function:
bool myClass::sortFunc(const int& i, const int& j) { return (words[i] < words[j]); }
The Error:
error: no matching function for call to ‘std::list<int, std::allocator<int> >::sort(<unresolved overloaded function type>)’ /usr/include/c++/4.4/bits/list.tcc:301: note: candidates are: void std::list<_Tp, _Alloc>::sort() [with _Tp = int, _Alloc = std::allocator<int>] /usr/include/c++/4.4/bits/list.tcc:378: note: void std::list<_Tp, _ Alloc>::sort(_StrictWeakOrdering) [with _StrictWeakOrdering = bool (SuperWordSearch::*) (const int&, const int&), _Tp = int, _Alloc = std::allocator<int>]
I have researched and come across the following questions:
C++ Custom compare function for list::sort
Problem sorting a list of pointers
Error in std::list::sort with custom comparator (expected primary-expression before ')' token)
and they would have been sufficient had it not been for the fact that in this class, the sortFunc depends on the member variable WORDS for that instance of the object. So I cannot make the comparator function (sortFunc) static or global
EDIT: Just came across this How to sort a std:list when you need member data? and it provides a solution by making a friend class, but is it possible to accomplish this inside the user-defined class itself?
-
Kerrek SB over 12 years@kol: You have to spell out the predicate yourself. Every lambda can trivially be expanded into a functor; it's just noisy. Do you need help with that?
-
encore2097 over 12 yearsHrm... I'm getting the following errors trying the bind method (Ubuntu linux x64, g++ v.4.4.3:)
error: ‘placeholders’ is not a namespace-name
error: expected namespace-name before ‘;’ token
error: ‘bind’ is not a member of ‘std’
error: ‘_1’ was not declared in this scope
error: ‘_2’ was not declared in this scope
-
encore2097 over 12 years@Kerrek SB: Thanks, forgot the specify the std. @ Rob: I'm not sure what you are referring to.
-
encore2097 over 12 yearsCan't beat the classiness of lambdas, but that requires a C++11 which I currently cannot use.