7
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <functional>
using namespace std;

template <typename Object, typename Comparator>
const Object &findMax(const vector<Object> &arr,
         const Comparator &isLessThan = less<Object>())
{
    int maxIndex = 0;

    for (int i = 1; i < arr.size(); i++) {
        if (isLessThan(arr[maxIndex], arr[i])) {
            maxIndex = i;
        }
    }
    return arr[maxIndex];
}

int main()
{
    vector<string> arr(3);
    arr[0] = "ZED";
    arr[1] = "alli";
    arr[2] = "crocode";
//...
    cout << findMax(arr) << endl;
    return 0;
}

When I compile it with g++, it gives the following error:

test4.cpp: In function ‘int main()’:
test4.cpp:48:24: error: no matching function for call to ‘findMax(std::vector<std::basic_string<char> >&)’
test4.cpp:48:24: note: candidate is:
test4.cpp:10:15: note: template<class Object, class Comparator> const Object& findMax(const std::vector<Object>&, const Comparator&)
2
  • 1
    I can't figure out your error, but you could consider std::max_element Commented Sep 24, 2013 at 11:58
  • Possible duplicate of C++ template function default value. Commented Jun 23, 2015 at 21:46

3 Answers 3

15

Template parameters cannot be deduced from default arguments. C++11, [temp.deduct.type]§5:

The non-deduced contexts are:

  • ...
  • A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done.
  • ...

You can get around this using overloading:

template <typename Object, typename Comparator>
const Object &findMax(const vector<Object> &arr, const Comparator &isLessThan)
{
    int maxIndex = 0;

    for (int i = 1; i < arr.size(); i++) {
        if (isLessThan(arr[maxIndex], arr[i])) {
            maxIndex = i;
        }
    }
    return arr[maxIndex];
}

template <typename Object>
const Object &findMax(const vector<Object> &arr)
{
    return findMax(arr, std::less<Object>());
}
Sign up to request clarification or add additional context in comments.

4 Comments

when 'findMax' is a function member of a class template it works well.why?
@tangwenqiang You mean it's a member function template? Or is it a plain member function and Comparator is a template parameter of the enclosing class template?
1 #include <iostream> 2 using namespace std; 3 template <typename Object> 4 //class A { 5 // public: 6 Object retself(const Object &initVal = Object()) 7 { 8 return initVal; 9 } 10 //}; 11 int main() 12 { 13 //A<int> test; 14 cout << retself() << endl; 15 return 0; 16 } run it(will get error); delete the '//', replace line 14 with 'cout << test.retself() << endl (will be ok); I want to konw why?
@tangwenqiang Because when it's a non-template member function of a class template, the template parameter comes from the enclosing class template and does not have to be deduced. So no problem there.
5

Default the template argument and the function argument. Use max_element (actually, don't even define this function, just use max_element wherever you would have called this).

template <typename Object, typename Comparator = std::less<Object>>
const Object &findMax(const vector<Object> &arr, Comparator comp = Comparator())
{
    return *std::max_element(arr.cbegin(), arr.cend(), comp);
}

Disclaimer: not tested, and must have C++11

Comments

4

Using default template parameters in C++11, your function could be written this way:

template <typename Object, typename Comparator = std::less<Object> >
const Object &findMax(const vector<Object> &arr, const Comparator isLessThan = Comparator())
{
    int maxIndex = 0;

    for (int i = 1; i < arr.size(); i++) {
        if (isLessThan(arr[maxIndex], arr[i])) {
            maxIndex = i;
        }
    }
    return arr[maxIndex];
}

Note the usage of default template parameter typename Comparator = std::less<Object>.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.