0

How can I have a templated function as a parameter for another function, with a default value?

For example, if I wanted to supply a function with a templated sort function, but have it default to std::sort, what would that look like?

The following does not work:

#include <algorithm> // std::sort

template <class iterator_type, class sort_comparison>
void temp(void (*sort_func)(iterator_type, iterator_type, sort_comparison) = std::sort)
{
    return;
}



int main()
{
    temp();

    return 0;
}

It still seems to require a supplied parameter according to the gcc errors.

metamorphosis
  • 1,972
  • 16
  • 25

1 Answers1

3

An alternative and less constrained solution is to wrap std::sort or another function template invocation into a lambda object:

template <class Container, class Sort>
void temp(Container& c, Sort sort) {
    sort(c);
}

template <class Container>
void temp(Container& c) {
    temp(c, [](auto& c) { std::sort(c.begin(), c.end()); });
}

int main() {
    std::vector<int> v;
    temp(v);
    temp(v, [](auto& c) { std::stable_sort(c.begin(), c.end()); });

    std::list<int> l;
    temp(l, [](auto& c) { c.sort(); }); // std::sort is incompatible with std::list
}

In C++03 lambda expressions aren't available (there are limited substitutes like boost::lambda but it has exactly the same limitation that it needs a pointer to function, cannot call a function template, unlike C++11 lambda), so that you have to code that functional class explicitly (but it gives you more flexibility with overloading):

struct Sort {
    template<class C>
    void operator()(C& c) {
        std::sort(c.begin(), c.end());
    }

    template<class T, class A>
    void operator()(std::list<T, A>& c) {
        c.sort();
    }
};
// ...
    temp(v, Sort());
    temp(l, Sort());

Still though, that is probably the simplest, fastest to compile and execute solution in C++03. It is verbose and non-local, but that is the best/simplest you can do in C++03.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271