Using Arguments to Specify Policy
Consider the earlier sort function template:
//
// templbubble.h
// Function Templates
//
// Created by Bryan Higgs on 10/11/24.
//
#ifndef templbubble_h
#define templbubble_h
#include <vector>
template<typename TYPE>
void sort(std::vector<TYPE> &v)
{
size_t n = v.size();
for (size_t i = 0; i < n - 1; i++)
{
for (size_t j = n - 1; i < j; j--)
{
if (v[j] < v[j - 1])
{ // swap v[j] and v[j-1]
TYPE temp = v[j];
v[j] = v[j-1];
v[j - 1] = temp;
}
}
}
}
#endif /* templbubble_h */What if we wanted to sort strings based on some other kind of collating sequence? For example, in a case-insensitive order, or in reverse order.
The sort algorithm doesn’t change. Only the comparison needs to change from:
if (v[j] < v[j - 1])
We simply need to generalize this to a compare operation, and then provide a mechanism to pass in the desired compare operation.
//
// PolicySort.h
// Function Overload Resolution
//
// Created by Bryan Higgs on 10/13/24.
//
#ifndef PolicySort_h
#define PolicySort_h
#include <vector>
template<typename TYPE, typename C>
void sort(std::vector<TYPE> &v)
{
size_t n = v.size();
for (size_t i = 0; i < n - 1; i++)
{
for (size_t j = n - 1; i < j; j--)
{
if (C::compare(v[j], v[j - 1]) < 0)
{ // swap v[j] and v[j-1]
TYPE temp = v[j];
v[j] = v[j-1];
v[j - 1] = temp;
}
}
}
}
#endif /* PolicySort_h */Here’s a class, Compare, with the necessary compare() class function:
//
// PolicyCompare.h
// Function Overload Resolution
//
// Created by Bryan Higgs on 10/13/24.
//
#ifndef PolicyCompare_h
#define PolicyCompare_h
// A 'policy' class
class Compare
{
public:
static int compare(const char *s1, const char *s2)
{
return strcmp(s1, s2); // compare in the normal way
}
};
#endif /* PolicyCompare_h */
Finally, here’s a main program to exercise this:
//
// PolicySort.cpp
// Function Overload Resolution
//
// Created by Bryan Higgs on 10/13/24.
//
#include <iostream>
#include "PolicySort.h"
#include "PolicyCompare.h"
void printVector(std::vector<const char *> v)
{
for(int i = 0; i < v.size(); i++)
std::cout << ' ' << v[i] << std::endl;
}
int main()
{
std::vector<const char *> vstrs(10);
vstrs[0] = "Vera";
vstrs[1] = "mary";
vstrs[2] = "fred";
vstrs[3] = "Zena";
vstrs[4] = "Algernon";
vstrs[5] = "carol";
vstrs[6] = "alan";
vstrs[7] = "Richard";
vstrs[8] = "Beatrice";
vstrs[9] = "xavier";
std::cout << "Before sorting: " << std::endl;
printVector(vstrs);
sort<const char *, Compare>(vstrs);
std::cout << "After sorting: " << std::endl;
printVector(vstrs);
return 0;
}… which produces the following:
Before sorting:
Vera
mary
fred
Zena
Algernon
carol
alan
Richard
Beatrice
xavier
After sorting:
Algernon
Beatrice
Richard
Vera
Zena
alan
carol
fred
mary
xavier
Program ended with exit code: 0
If we change the Compare class as follows:
//
// PolicyCompare.h
// Function Overload Resolution
//
// Created by Bryan Higgs on 10/13/24.
//
#ifndef PolicyCompare_h
#define PolicyCompare_h
// A 'policy' class
class Compare
{
public:
static int compare(const char *s1, const char *s2)
{
return -strcmp(s1, s2); // reverse compare
}
};
#endif /* PolicyCompare_h */
Now, the program outputs the reversed sort order:
Before sorting:
Vera
mary
fred
Zena
Algernon
carol
alan
Richard
Beatrice
xavier
After sorting:
xavier
mary
fred
carol
alan
Zena
Vera
Richard
Beatrice
Algernon
Program ended with exit code: 0
Similarly, we could simply pass in a different class with a different compare implementation to control sorting order in any way we wish.