Why doesn't this variadic template work?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<class T>
T max(T first, T second)
{
   return first > second ? first : second;
}

template<class T, class... Args>
T max(T elem, Args... args)
{
   return  elem > max(args...) ? elem : max(args...);
}

int main()
{	
   cout << max(7.5, 4.4, 8, 10, 3.5, 5);
} 


It says that max() requires 2 arguments but none is provided.

But why?

I tried to change the base case from max(T,T) to max(T,U)

1
2
3
4
5
template<class T, class U>
T max(T first, U second)
{
   return first > second ? first : second;
}


I just had this idea when I realized that the last two arguments that I pass to the function are 3.5 and 5 which are two different types.

But I don't think that was the error at all.

Because the compiler was complaining about NO ARGUMENTS PROVIDED
Make sure std::max is not interfering. Could happen if you have using namespace std; in the code.
"max() requires 2 arguments but none is provided" cannot be the entire error message.

gcc error message here: http://coliru.stacked-crooked.com/a/5030995f53def696
clang here: http://coliru.stacked-crooked.com/a/04df1d5cb26f4303

I think clang is the most direct:

main.cpp:12:19: error: no matching function for call to 'max'
   return  elem > max(args...) ? elem : max(args...);
                  ^~~
main.cpp:12:19: note: in instantiation of function template specialization 'max<int>' requested here
main.cpp:12:19: note: in instantiation of function template specialization 'max<double, int>' requested here
main.cpp:12:19: note: in instantiation of function template specialization 'max<int, double, int>' requested here
main.cpp:12:19: note: in instantiation of function template specialization 'max<int, int, double, int>' requested here
main.cpp:12:19: note: in instantiation of function template specialization 'max<double, int, int, double, int>' requested here
main.cpp:17:17: note: in instantiation of function template specialization 'max<double, double, int, int, double, int>' requested here
   std::cout << max(7.5, 4.4, 8, 10, 3.5, 5);
                ^
main.cpp:4:3: note: candidate function template not viable: requires 2 arguments, but 0 were provided
T max(T first, T second)
  ^
main.cpp:10:3: note: candidate function template not viable: requires at least argument 'elem', but no arguments were provided
T max(T elem, Args... args)
  ^
1 error generated.


it's showing how recursion led to the attempt to instantiate "max<double, int>", which missed your T,T overload and proceeded to recursive with T=double and Args...=int, which then proceeded to recurse with T=int and Args...= empty list, at which point neither overload works

I think a better terminating condition here would be single-argument list:
1
2
3
4
5
template<class T>
T max(T first)
{
   return first;
}

(also, passing everything by value may not be the good idea either)
Last edited on
Topic archived. No new replies allowed.