I have a problem with calling a function:
namespace Sort {
enum Type {
insertion, selection, merge
};
template <class Elem = int, class Container = std::vector<Elem>>
void sort(std::shared_ptr<Container> vectorPointer,
std::function<bool(Elem, Elem)> comparator = std::less<Elem>(),
Type type = selection) {
switch (type) {
case insertion:
insertionSort(vectorPointer, comparator);
case selection:
selectionSort(vectorPointer, comparator);
case merge:
mergeSort(vectorPointer, comparator);
}
}
}
When I call it as such:
std::shared_ptr<std::vector<int>> intVector;
Sort::sort(intVector);
Everything is OK, however if I start replacing the default parameters:
Sort::sort(intVector, std::less<int>(), merge);
I get an error message: Candidate template ignored: could not match 'function' against 'less'
Update:
I finally made it work - explicitly specializing the function call seemed to do the trick. Also, I didn't provide the namespace for the enum value.
Sort::sort<int, std::vector<int>>(intVector, std::less<int>(), Sort::merge)
Thanks guys!
template <class Elem = int, class Container = std::vector<Elem>>
void sort(std::shared_ptr<Container> vectorPointer,
std::function<bool(Elem, Elem)> comparator = std::less<Elem>(),
Type type = selection)
The comparator type depends on the template parameter Elem, so when the compiler performs template deduction rules it requires that the caller's provided value has a type that matches the type pattern of the argument. Since 'less' and 'function' are not the same type, this function is not a valid match.
(Do not confuse the type deduction logic to be the same as the conversion sequence allowed when dealing with instances of these types.)
If you change your call to look like this it would work (though obviously you wouldn't want to do it due to the awful user experience):
Sort::sort(shV, std::function<bool(int, int)>(std::less<int>()), Sort::merge);
This way, the type of the 2nd argument is matching what the template expects. The above example also solves your use of the 'merge' enumerator, which is in the Sort namespace and requires namespace qualification.
A small change to your signature, taking Compare as another template parameter, is a possibility:
template <class Elem = int, class Container = std::vector<Elem>,
class Compare = std::less<Elem>>
void sort(std::shared_ptr<Container> vectorPointer,
Compare comparator = Compare(),
Type type = selection) {
switch (type) {
// ...
}