Reputation: 30723
I ma writing a template function that takes a vector of elements and does a sequence of some operations on it. One of these operation is std::sort().
Naturally, client code needs to supply a comparator functor. I do not want the client code to specify a value for this parameter if it passes in a container of well-known types (ints, strings, etc.). How should I define the default value of my Comp template parameter?
template<typename Container, typename Comp=????>
void my_func(Container elements, Comp comp) {
...
std::sort(elements.begin(), elements.end(), comp);
...
}
Upvotes: 1
Views: 1814
Reputation: 7357
In your example there is 2 issues:
to make default behavior you must suplly less<T>
as a functor.
Your function is taking a copy so, the copy will be sorted, unless you take a refence to Container
instead.
Example how to make this:
#include <functional>
template<typename Container, typename Comp=std::less<typename Container::value_type> >
void my_func(Container &elements, Comp comp = Comp() )
{
std::sort(elements.begin(), elements.end(), comp);
}
// A partial specialisation for std::list
#include <list>
template<typename ContainerValueType, typename Allocator, typename Comp=std::less<ContainerValueType> >
void my_func(std::list<ContainerValueType, Allocator> &elements, Comp comp = Comp() )
{
elements.sort(comp);
}
Upvotes: 0
Reputation: 2435
std::sort uses "Less" as default comparator. So to keep it consistent:
template<typename Container, typename Comp = std::less<typename Container::value_type> >
void my_func(Container& elements, Comp comp = Comp())
{
std::sort(elements.begin(), elements.end(), comp);
}
Upvotes: 2
Reputation: 21317
I wouldn't default the template itself but rather the parameter of the function into something akin to std::greater
or std::less
for >
and <
respectively. std::sort
uses std::less
by default.
If you want to get the template parameter for it then there is a proposal to make std::greater<>
to work for generalised types called N3421 that was actually accepted for C++14.
However until then you can do std::greater<typename Container::value_type>
. You can opt to remove the reference or cv qualifiers using type_traits if you wish.
<functional>
has other default comparisons but those two are the most common.
So a "complete" solution would be something like this:
template<typename Container, typename Comp>
void my_func(Container& elements, Comp comp = std::less<typename Container::value_type>()) {
std::sort(elements.begin(), elements.end(), comp);
}
Upvotes: 0
Reputation: 47619
#include <vector>
#include <algorithm>
template<typename Container, typename Comp=std::less<typename Container::value_type>>
void my_func(Container elements, Comp comp = Comp()) {
//...
std::sort(elements.begin(), elements.end(), comp);
//...
}
int main() {
std::vector<int> v;
my_func(v);
}
Note also Comp comp = Comp()
Upvotes: 0