The right way to do this in C ++ is through templates.
Sorting something is an algorithm, and it usually has almost no permanent state. Sorting is not an object - it is a function for data (which can be objects).
The std library already has sorting with this signature:
template<typename I, typename C = std::less<typename std::iterator_traits<I>::value_type> > void sort(I begin, I end, C comp = C());
The begin and end iterators denote the range of values ββto be sorted, and comp is a functor (or function) that, when passing two elements of the range of values, indicates whether the first of them is smaller than the second.
To use this in std::vector , you would do something like this:
std::vector<int> myVector;
std :: sort (usually?) - quicksort. But the interface works for quick, bubble and sort insertion.
A big advantage of this approach is that one species can use the other. As an example, while quicksort is faster on large datasets, often on small datasets it is easy to sort the insert (lower constant coefficient, even with an overhead of n ^ 2). Thus, by writing down these types, quicksort recursive calls can instead be inserted into sorting when the number of items is small.
Now, if you need a temporary replacement for the algorithm that you are using, you will need to indicate which iterators you are using, and possibly even which comparator. This can be done either with a common function signature (what I would do), or with a base class with a clean virtual interface (which I would advise). Note that the overhead for the selected comparison time is not trivial. Overhead from a fixed iterator selection or from calling a function pointer or a virtual method, if it is not executed when recursive calls to your algorithm, will be quite cheap for any container of a reasonable size.