简体   繁体   中英

Default argument in function template C++

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)

There are a number of things to say:

  1. 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.

  2. 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).

  3. 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 , ie 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. Eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM