@j73g2000cwa.googlegroups.com>,
(e-mail address removed) says...
Hi,
Thanks. I have one more question, if x,y and z are of different data
types, say two are strings and one int, how should I define the
operator to handle different data types?
As long as all the data types support the < operator,
it's irrelevant.
Since there are five such
fields on which teh ordering is to be done, i am planning to define
just five functions depending on the number of parameters and not on
specific types [otherwise i need to have all possible
combinations!!!!].How can I make the operator able to handle both
string as well as integer?
As long as you always use the fields in the same order,
you can pretty easily get by with only one comparison
functor, and specify the fields to be used when you
construct the comparison object:
// for the moment, I'll only do three fields, but each
// of a different type.
struct record {
int x;
std::string y;
long z;
};
struct order {
// each of these must be a power of 2
enum { by_x = 1, by_y = 2, by_z = 4};
int fields_;
order(int fields) : fields_(fields) {}
bool operator()(record const &a, record const &b)
{
if (fields_ & by_x) {
if (a.x < b.x)
return true;
else if (a.x > b.x)
return false;
}
if (fields_ & by_y) {
// compare by field y
}
if (fields_ & by_z) {
// compare by field z
}
}
};
To use this, you'd specify the fields to sort on when you
construct your comparison object. For example, to compare
based on fields x and z, you'd specify:
std::sort(records.begin(), records.end(),
order(order::by_x | order::by_z));
Arguably, using '&' to connect the field specifiers would
make look more sensible. If you don't mind a little
ugliness inside the class, it's pretty easy to support
that as well -- you just need to invert the sense of
everything:
struct order {
enum {
by_x = (-1 & ~1),
by_y = (-1 & ~2),
by_z = (-1 & ~4)
};
int fields_;
order(int fields) : fields_(fields) {}
bool operator()(record const &a, record const &b) {
if (!(fields_ & by_x)) {
if (a.x < b.x)
return true;
if (a.x > b.x)
return false;
}
if (!(fields_ & by_y)) {
if (a.y < b.y)
return true;
if (a.y > b.y)
return false;
}
if (!(fields_ & by_z)) {
if (a.z < b.z)
return true;
if (a.z > b.z)
return true;
}
return false;
}
};
then the sort would look like this:
std::sort(records.begin(), records.end(),
order(order::by_x & order::by_z));
It's probably open to argument whether this is really
even syntactic sugar, or really syntactic saccharin.