Re: std::sort (AGAIN)
On 23 Mai, 00:36, none <n...@none.none> wrote:
I want to sort a vector of structs. The catch is that the user can sel=
ect
which fields in the struct are used for the sort. That alone I can do,=
but
what I can't do is make it work with member functions. From what I can
gather in the FAQ, there are a few possibilities:
As Juha wrote you can simply use pointers to a functions like
bool cmp_first_name(YourType const& a, YourType const& b);
In case you really want to sort "structs" (with public members) you
can do something like this:
template<typename S, typename C>
class member_comparator {
S C::*pm;
public:
explicit member_comparator(S C::*p) : pm(p) {}
bool operator()(C const& a, C const& b) const
{return a.*pm < b.*pm;}
};
template<typename S, typename C>
member_comparator<S,C> make_memcmp(S C::*p) {
return member_comparator<S,C>(p);
}
...
void foo(std::vector<YourType> & vec) {
std::sort(vec.begin(), vec.end(),
make_memcmp(&YourType::first_name));
}
provided that YourType has a public member called first_name that is
comparable.
Another thing: If you don't provide your own swap function for
YourType the sort algorithm will fall back on an unspecialized
std::sort which might be slower than necessary. In case your struct
contains objects of type std::string or some other members that swap
quickly but copy slowly you should supply your own swap function.
struct YourType {
std::string first_name;
std::string last_name;
int age;
void swap(YourType & x);
};
void YourType::swap(YourType & x) {
// string::swap is FAST
first_name.swap(x.first_name);
last_name.swap(x.last_name);
std::swap(age,x.age);
}
// non-templated swap, can be found via ADL
inline swap(YourType & a, YourType & b) {a.swap(b);}
// specialization of std::swap to be on the safe side.
namespace std {
template<> swap<YourType>(YourType & a, YourType & b)
{a.swap(b);}
}
hth,
SG