I would like to sort a vector
vector object;
Where myclass
contains many int
variabl
this is my approach to solve this generally. It extends the answer from Steve Jessop by removing the requirement to set template arguments explicitly and adding the option to also use functoins and pointers to methods (getters)
#include
#include
#include
#include
#include
using namespace std;
template
struct CompareByGetter {
U (T::*getter)() const;
CompareByGetter(U (T::*getter)() const) : getter(getter) {};
bool operator()(const T &lhs, const T &rhs) {
(lhs.*getter)() < (rhs.*getter)();
}
};
template
CompareByGetter by(U (T::*getter)() const) {
return CompareByGetter(getter);
}
//// sort_by
template
struct CompareByMember {
U T::*field;
CompareByMember(U T::*f) : field(f) {}
bool operator()(const T &lhs, const T &rhs) {
return lhs.*field < rhs.*field;
}
};
template
CompareByMember by(U T::*f) {
return CompareByMember(f);
}
template
struct CompareByFunction {
function f;
CompareByFunction(function f) : f(f) {}
bool operator()(const T& a, const T& b) const {
return f(a) < f(b);
}
};
template
CompareByFunction by(function f) {
CompareByFunction cmp{f};
return cmp;
}
struct mystruct {
double x,y,z;
string name;
double length() const {
return sqrt( x*x + y*y + z*z );
}
};
ostream& operator<< (ostream& os, const mystruct& ms) {
return os << "{ " << ms.x << ", " << ms.y << ", " << ms.z << ", " << ms.name << " len: " << ms.length() << "}";
}
template
ostream& operator<< (ostream& os, std::vector v) {
os << "[";
for (auto it = begin(v); it != end(v); ++it) {
if ( it != begin(v) ) {
os << " ";
}
os << *it;
}
os << "]";
return os;
}
void sorting() {
vector vec1 = { {1,1,0,"a"}, {0,1,2,"b"}, {-1,-5,0,"c"}, {0,0,0,"d"} };
function f = [](const mystruct& v){return v.name;};
cout << "unsorted " << vec1 << endl;
sort(begin(vec1), end(vec1), by(&mystruct::x) );
cout << "sort_by x " << vec1 << endl;
sort(begin(vec1), end(vec1), by(&mystruct::length));
cout << "sort_by len " << vec1 << endl;
sort(begin(vec1), end(vec1), by(f) );
cout << "sort_by name " << vec1 << endl;
}