Re: std::sort (AGAIN)
On 26 Mai, 22:02, none <n...@none.none> wrote:
The type being sorted is not the same as the type (class) doing the
sorting. In other words, to expand on your example, this is illegal:
class B
{
int x;
int y;
};
class A
{
bool z;
public:
static bool comparator(const B& lhs, const BA& rhs)
{
return z ? (lhs.x < rhs.x) : (lhs.y < rhs.y);
}
};
Pretty much yes. Because of two reasons:
(1) x and y are private members of B you can't access from
the function "comparator".
(2) z is a non-static member of A so "comparator" cannot be a
static member function. A static member has no implicit
this-pointer. (!)
But that is what I really want to do. I think that Bart, SG, and floyd
have provided the answer, but I'm not thrilled about it. :) I find
Boost to be a little bloated.
The fact that what I want to do is not supported directly by std::sort()
makes me think that my approach is probably just bad from the start.
How would you guys approach the problem?
I already answered that. :) The key here is to use a comparator that
has a "state" (parameters). std::sort supports more than pure function
pointers. It also accepts objects with overloaded function call
operator. Here is a non-generic example:
#include <vector>
#include <algorithm>
#include <iostream>
#include <string>
struct entry {
std::string name;
int age;
explicit entry(std::string n, int a) : name(n), age(a) {}
};
bool comp_name(entry const& a, entry const& b)
{return a.name < b.name;}
bool comp_age(entry const& a, entry const& b)
{return a.age < b.age;}
class multi_compare {
public:
// declared comp_t to be a function pointer type
typedef bool (*comp_t)(entry const&, entry const&);
multi_compare(comp_t pf1, comp_t pf2)
{c[0] = pf1; c[1] = pf2;}
bool operator()(entry const& a, entry const& b) const {
for (int i=0; i<2; ++i) {
comp_t pf = c[i];
if (pf==0) break;
if (pf(a,b)) return true;
if (pf(b,a)) return false;
}
return false;
}
private:
comp_t c[2];
};
int main() {
std::vector<entry> vec;
vec.push_back(entry("Jack",43));
vec.push_back(entry("Hugo",33));
vec.push_back(entry("Kate",29));
std::sort(vec.begin(), vec.end(),
multi_compare(comp_name,comp_age) );
for (int idx=0, n=vec.size(); idx<n; ++idx) {
entry const& e = vec.at(idx);
std::cout << e.name << " is " << e.age << " years old.\n";
}
}
Cheers!
SG