You essentially want to write two functions, each of which knows its sort order statically (ie, at compile time), and choose which one to call dynamically.
The simplest change is this:
// original code, templated
template <bool Ascending>
void Array::sort() {
int i,j;
Data* buffer;
for (i=1; i<_size; i++) {
buffer = vect[i];
j=i-1;
while (j>=0 && (Ascending?(vect[j]->key > buffer->key):(vect[j]->key < buffer->key)))
{
vect[j+1] = vect[j];
j--;
}
vect[++j] = buffer;
}
}
// original prototype
void Array::sort(int order) {
if (order > 0)
sort<true>();
else if (order < 0)
sort<false>;
}
Note that although there is still a ternary statement in the inner loop, it can easily be optimised away since Ascending
is constant (just a different constant in each instantiation).
A cleaner way is to remove the ternary statement entirely, and and instead pass some kind of comparison function into the inner function template. We could pass a function pointer, or a lambda - I'm using the built-in function objects since they already do what we want.
// Comparitor is some type you can call to compare two arguments
template <typename Comparitor>
void Array::sort(Comparitor comp) {
int i,j;
Data* buffer;
for (i=1; i<_size; i++) {
buffer = vect[i];
j=i-1;
while (j>=0 && comp(vect[j]->key, buffer->key)) {
vect[j+1] = vect[j];
j--;
}
vect[++j] = buffer;
}
}
// std::greater and less come from <functional>
void Array::sort(int order) {
typedef decltype(vect[0]->key) KeyType; // or use the real type directly
if (order > 0)
sort(std::greater<KeyType>());
else if (order < 0)
sort(std::less<KeyType>());
}