Reputation: 826
Suppose that I have a struct Node
which contains x
and y
and I would like to create a vector of these Node
s.
struct Node {
int x;
int y;
Node(int x, int y);
};
vector<Node *> nodes;
I would like to write various functions that work either on x
or y
. For example, I want to write a sort
function that sorts the nodes vector by x
coordinates and another one which sorts based on y
.
It is definitely a better idea to write a single function that implements both sort_by_x and sort_by_y. I was thinking of writing a function which takes a bool
like isX
and performs the sorting accordingly. However, I would like to avoid writing the same code twice (once for x and once for y). I want to write a single piece of code that performs the corresponding sorting. I tried to implement this using the following code, but it is not valid in C++ (because it expects c
to be one of the variables in Node
).
void mySort(vector<Node *> &nodes, bool isX) {
char c;
if (isX) {
c = 'x';
}
else {
c = 'y';
}
// some code
nodes[i]->c // if c == 'x', x will be used, otherwise y.
}
Would you please let me a workaround to rewrite the above code or some other way of implementing the same functionalities based on different variables?
Upvotes: 3
Views: 85
Reputation: 42858
You don't have to write your own function to do the sorting. The standard library already has a generic sort
function. You can use it like this:
auto x_comparator = [](auto a, auto b) { return a->x < b->x; }
auto y_comparator = [](auto a, auto b) { return a->y < b->y; }
std::sort(nodes.begin(), nodes.end(), x_comparator); // sort by x
std::sort(nodes.begin(), nodes.end(), y_comparator); // sort by y
Upvotes: 1
Reputation: 18974
You can use a pointer to member here:
int Node::*m;
if (isX) {
m = &Node::x;
}
else {
m = &Node::y;
}
// some code
nodes[i]->*m
The syntax is fairly ugly, but it does exactly what you're trying to do. If you have C++11 available an alternative would be to write simple lambda functions to return x
or y
and store them in a std::function
; this is slightly less efficient, but less ugly and more general.
Upvotes: 4
Reputation: 70482
std::sort
allows a comparator to be passed in as a third argument. You can change the behavior of the sort by using a different comparator for the x
case and the y
case.
std::sort(nodes.begin(), nodes.end(),
[](const Node *a, const Node *b) -> bool {
return a->x < b->x;
});
Upvotes: 3