Just to be sure, from what I've read and tried, I can't put a default argument in a function template correct? I've picked that much up both from my compiler AND from what other's have responded with... I'm asking because I'm a newb and some of the more technical responses are hard to understand. Is there a work around for this? I'm trying to create a findmax function that uses a default relational operator but with the option to overload...ie:
template <typename Type, typename Compare = std::less<Type> >
Type FindMax(std:vector<Type> &vec, Compare comp = Compare()) {
return *std::max_element(...
}
I suppose I could make a class for this but it seems like a lot of work when all I really want is one function... Thanks!
I should add another question as well about something that I've seen before:
What does this function tempate do, specifically, what is the (cmpFn)...) default argument doing?
template <typename ElemType>
ElemType FindMax(Vector<ElemType> &v, int (cmpFn)(ElemType, ElemType) = OperatorCmp)
You cannot give default arguments to the same template parameters in different declarations in the same scope. The compiler will not allow the following example: template<class T = char> class X; template<class T = char> class X { };
C has no default parameters.
A default argument is a value provided in a function declaration that is automatically assigned by the compiler if the calling function doesn't provide a value for the argument.
For non-template functions, default arguments can be added to a function that was already declared if the function is redeclared in the same scope. At the point of a function call, the defaults are a union of the defaults provided in all visible declarations for the function.
There are a number of things to say:
What you defined is a function template, not a class template. Since you are using a default template parameter
typename Compare = std::less<Type>
I presume you are already using C++11, because for all I know function templates did not allow default template parameters in the previous versions of the standard.
On the other hand, default arguments of template parameters like this
Compare comp = Compare()
were possible in the previous version of the standard, too. Your statement that default arguments are not possible for templated parameters is wrong (or perhaps it actually referred to what I called default template parameters above).
The compiler error messages that you receive must be due to some other problem. Perhaps the Type
you end up using does not go well with std::less
, or the Compare
type you use does not implement the default constructor. In any case, the following program compiles on GCC 4.6.2 (note that I changed the std::vector<> &
to const std::vector<> &
because that seemed more right):
#include <vector>
#include <functional>
#include <algorithm>
template <typename Type, typename Compare = std::less<Type> >
Type FindMax(const std::vector<Type> &vec, Compare comp = Compare()) {
return *std::max_element(vec.begin(),vec.end(),comp);
}
int main() {
FindMax(std::vector<int>());
return 0;
}
And indeed this requires the -std=C++0x
option, but that is because the default template parameter, not the default argument.
About the extra question related to cmpFn
:
That declares a function parameter, i.e. an argument that is itself a function. The declaration
int (cmpFn)(ElemType, ElemType)
means the local name of the function is cmpFn
, its return type is int
, and it takes two arguments, both of type ElemType
. The idea is that the caller can pass a function (or a functor) that will then be used to compare the elements of the vector. E.g. if you define the default value of that argument OperatorCmp
before the function declaration like this:
int OperatorCmp(int a, int b) {
return (a<b?-1:(a>b?1:0));
}
the declaration becomes valid and you can use it to find the maximum value of a std::vector<int>
.
You can do that in C++11. As of C++03 you can easily work around it by creating two overloads with different number of arguments and forwarding from one to the other.
template <typename Type>
Type findMax( std::vector<Type> const & v ) {
return findMax( v, std::less<Type>() );
}
Alternatively you can use the standard algorithms and avoid having to write your own.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With